commit 1a8f27c35024af7b4ed857a388d20f0a4a560db0 from: rsc date: Fri May 14 15:14:21 2004 UTC various bug fixes commit - a796abef1632f379ced703b1b2e691d8f63436e2 commit + 1a8f27c35024af7b4ed857a388d20f0a4a560db0 blob - /dev/null blob + 4cdc6b24a66d05979963666d18a2fb79b2df0ef8 (mode 644) --- /dev/null +++ man/man1/graph.1 @@ -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. blob - /dev/null blob + cd1a1b8160601cce614f10c2ef0bcb9eaa5e97d7 (mode 644) --- /dev/null +++ man/man1/plot.1 @@ -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) blob - /dev/null blob + d08aca3bb29e2130291ff48c7dd84c923f7acc85 (mode 644) --- /dev/null +++ man/man5/venti.conf.5 @@ -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) blob - /dev/null blob + be112a6af8d98fa97a344b21fb207976ea59e259 (mode 644) --- /dev/null +++ man/man8/venti.8 @@ -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. blob - /dev/null blob + fb6d852271223dfde1b6923f26db4f68da2c6d4c (mode 644) --- /dev/null +++ man/man8/ventiaux.8 @@ -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. blob - /dev/null blob + 39bb8099db08fd35244944dfacf7b8f1b178d912 (mode 644) --- /dev/null +++ sky/.cvsignore @@ -0,0 +1,2 @@ +*.scat +constelnames blob - 7dc1e88b64f0fff5d5d26af9fc8f6ce6209534bc blob + 3bc1037105945ce46816a5889c2c206d9317daa9 --- src/cmd/acme/exec.c +++ src/cmd/acme/exec.c @@ -1308,7 +1308,7 @@ runproc(void *argvp) name[e-t] = 0; e = utfrrune(name, '/'); 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 */ c->name = bytetorune(name, &c->nname); free(name); blob - 11014c2cdbacd5d5b7e9069a2597448b946db42f blob + 9fa5424821df3c0938d6a5411d42382f0f6f2fde --- src/cmd/acme/rows.c +++ src/cmd/acme/rows.c @@ -663,12 +663,12 @@ rowload(Row *row, char *file, int initing) break; wincleartag(w); textinsert(&w->tag, w->tag.file->b.nc, r+n+1, nr-(n+1), TRUE); - free(r); if(ndumped >= 0){ /* simplest thing is to put it in a file and load that */ sprint(buf, "/tmp/d%d.%.4sacme", getpid(), getuser()); fd = create(buf, OWRITE|ORCLOSE, 0600); if(fd < 0){ + free(r); warning(nil, "can't create temp file: %r\n"); goto Rescue2; } @@ -679,6 +679,7 @@ rowload(Row *row, char *file, int initing) if(rune == '\n') line++; if(rune == (Rune)Beof){ + free(r); Bterm(bout); free(bout); close(fd); @@ -696,6 +697,7 @@ rowload(Row *row, char *file, int initing) winsettag(w); }else if(dumpid==0 && r[ns+1]!='+' && r[ns+1]!='-') get(&w->body, nil, nil, FALSE, XXX, nil, 0); + free(r); if(fontr){ fontx(&w->body, nil, nil, 0, 0, fontr, nfontr); free(fontr); blob - aa58be1a59e56db3bdfc2e99a97be7386c4a7a38 blob + 37613d805e57f868ae55c2b987949ed1282c6d4e --- src/cmd/acme/text.c +++ src/cmd/acme/text.c @@ -963,8 +963,11 @@ textshow(Text *t, uint q0, uint q1, int doselect) int nl; uint q; - if(t->what != Body) + if(t->what != Body){ + if(doselect) + textsetselect(t, q0, q1); return; + } if(t->w!=nil && t->fr.maxlines==0) colgrow(t->col, t->w, 1); if(doselect) blob - /dev/null blob + 7d5e21ebf337de43ead276bd3138130ba06469aa (mode 644) --- /dev/null +++ src/lib9/rendez-futex.c @@ -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 +typedef u32int u32; +#include +#include +#define __user +#include +#include +#include + +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; +} + blob - 801c39309b0c8436f1ca8d9605e0f525a07eb1c3 blob + b4204f4e1e2c9ba81dc2966187689f22742a6ed2 --- src/libdraw/md-alloc.c +++ src/libdraw/md-alloc.c @@ -86,7 +86,13 @@ _allocmemimage(Rectangle r, u32int chan) return nil; 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){ free(md); return nil; blob - 3151525080c0ef7feaeec1cbfd41428e48a318bb blob + a42af96bb807cf21df910ef1e0ed550e9fe27970 --- src/libfs/fs.c +++ src/libfs/fs.c @@ -86,19 +86,27 @@ fsunmount(Fsys *fs) void _fsdecref(Fsys *fs) { - Fid *f, *next; + Fid *f, **l, *next; qlock(&fs->lk); --fs->ref; //fprint(2, "fsdecref %p to %d\n", fs, fs->ref); if(fs->ref == 0){ 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){ next = f->next; - if(f->fid%Fidchunk == 0) - free(f); + free(f); } free(fs); + return; } qunlock(&fs->lk); } blob - 28c9d1cfd9bef4c0d5f4d3b779f4a15f8cbf8654 blob + 763080ba18dba35f01b933358dd21d7f7e7c825e --- src/libfs/ns.c +++ src/libfs/ns.c @@ -23,8 +23,11 @@ nsmount(char *name, char *aname) fd = dial(addr, 0, 0, 0); if(fd < 0){ werrstr("dial %s: %r", addr); + free(addr); return nil; } + free(addr); + fcntl(fd, F_SETFL, FD_CLOEXEC); fs = fsmount(fd, aname); blob - e583da60dc84a41c793be690bc67387c01ff9592 blob + b544f16de2ea2dfe7216a23cb2537d31ed2f5fdd --- src/libthread/fdwait.c +++ src/libthread/fdwait.c @@ -174,8 +174,8 @@ _threadfdwait(int fd, int rw, ulong pc) struct { Channel c; - Alt *qentry[2]; ulong x; + Alt *qentry[2]; } s; threadfdwaitsetup(); @@ -214,11 +214,15 @@ threadsleep(int ms) struct { Channel c; ulong x; + Alt *qentry[2]; } s; threadfdwaitsetup(); 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; sleeptime[nsleep++] = p9nsec()/1000000+ms; recvul(&s.c);