Date: 2008-09-13 00:27:47 +0200 (Sat, 13 Sep 2008)
New Revision: 934
OLPC trac 8139 - Performance improvement in deblocker - don't read
data into buffer if the data is going to be overwritten.
--- forth/kernel/kernel.fth 2008-09-12 22:23:45 UTC (rev 933)
+++ forth/kernel/kernel.fth 2008-09-12 22:27:47 UTC (rev 934)
@@ -2061,13 +2061,16 @@
+: align-byte# ( d.byte# -- d.aln-byte# ) fid @ alignop @ execute ;
+: byte#-aligned? ( d.byte# -- flag ) 2dup align-byte# d= ;
\ An implementation factor which
\ fills the buffer with a block from the current file. The block will
\ be chosen so that the file address "d.byte#" is somewhere within that
: fillbuf ( d.byte# -- )
- fid @ alignop @ execute ( d.byte# ) \ Aligns position to a buffer boundary
+ align-byte# ( d.byte# ) \ Aligns position to a buffer boundary
2dup fstart 2! ( d.byte# )
fid @ seekop @ execute ( )
bfbase @ bflimit @ over - ( adr #bytes-to-read )
@@ -2080,8 +2083,40 @@
\ returns the address within the buffer corresponding to the
\ selected position "d.byte#" within the current file.
+: bufaddr> ( bufaddr -- d.byte# ) bfbase @ - s>d fstart 2@ d+ ;
: >bufaddr ( d.byte# -- bufaddr ) fstart 2@ d- drop bfbase @ + ;
+\ This is called from fputs to open up space in the buffer for block-sized
+\ chunks, avoiding prefills that would be completely overwritten.
+: prefill? ( endaddr curaddr -- endaddr curraddr flag )
+ \ If the current buffer pointer is not block-aligned, must prefill
+ bfcurrent @ bufaddr> byte#-aligned? 0= if true exit then ( end curr )
+ 2dup - 0 align-byte# drop ( end curr aln-size )
+ \ If the incoming data won't fill a block, must prefill
+ ?dup 0= if true exit then ( end curr aln-size )
+ \ If there is still space in the buffer, just open it up for copyin
+ bflimit @ bfend @ - ?dup if ( end curr aln-len buffer-avail )
+ min bfend +! false exit
+ then ( end curr aln-len )
+ \ Save current on stack because ?flushbuf clears it
+ bfcurrent @ ( end curr aln-len current )
+ \ The buffer is full; clear out its old contents
+ ?flushbuf ( end curr aln-len )
+ \ Advance the file pointer to the new buffer starting position
+ bufaddr> fstart 2! ( end curr aln-len )
+ bfbase @ + bflimit @ umin bfend ! ( end curr ) \ Room for new bytes
+ bfbase @ dup bftop ! bfcurrent ! ( end curr ) \ No valid bytes yet
\ An implementation factor which
\ advances to the next block in the file. This is used when accesses
\ to the file are sequential (the most common case).
@@ -2352,8 +2387,16 @@
over bfend @ bfbase @ - u>= or if ( d.byte# offset )
\ Not in buffer
\ Flush the buffer and get the one containing the desired byte.
- drop ?flushbuf 2dup fillbuf ( d.byte# )
- >bufaddr ( bufaddr )
+ drop ?flushbuf ( d.byte# )
+ 2dup byte#-aligned? if ( d.byte# )
+ \ If the new offset is on a block boundary, don't read yet,
+ \ because the next op could be a large write that fills the buffer.
+ fstart 2! ( )
+ bfbase @ dup bftop ! dup bfend ! ( bufaddr )
+ 2dup fillbuf ( d.byte# )
+ >bufaddr ( bufaddr )
+ then ( bufaddr )
\ The desired byte is already in the buffer.
nip nip bfbase @ + ( bufaddr )
@@ -2429,13 +2472,14 @@
\ Writes count bytes from memory starting at "adr" to the current file
: fputs ( adr count fd -- )
file @ >r file !
- over + swap ( endaddr startaddr )
- begin copyin 2dup u>
- \ Here there should be some code to see if there are enough remaining
- \ bytes in the request to justify bypassing the file buffer and writing
- \ directly from the user's buffer. 'Enough' = more than one file buffer
- sync bfcurrent @ shortseek ( endaddr curraddr )
+ over + swap ( endaddr startaddr )
+ begin copyin 2dup u> while ( endaddr curraddr )
+ sync ( endaddr curraddr )
+ \ Prefill? tries to avoid unnecessary reads by opening up space
+ \ in the buffer for chunks that will completely fill a block.
+ prefill? if ( endaddr curraddr )
+ bfcurrent @ shortseek ( endaddr curraddr )
r> file !
Date: 2008-09-13 00:23:45 +0200 (Sat, 13 Sep 2008)
New Revision: 933
OLPC trac 8450 - ask explicitly for several DHCP parameters.
--- ofw/inet/dhcp.fth 2008-09-12 20:54:20 UTC (rev 932)
+++ ofw/inet/dhcp.fth 2008-09-12 22:23:45 UTC (rev 933)
@@ -155,9 +155,22 @@
\ Options common to discover, inform, and request messages
: other-parameters ( -- )
+ \ Parameter request list
+ \ h# 01 - 1 Subnet mask
+ \ h# 03 - 3 Router IP address
+ \ h# 06 - 6 Name Server IP address
+ \ h# 0c - 12 Client name
+ \ h# 0f - 15 Domain name
+ \ h# 11 - 17 Root path
+ \ h# 1c - 28 Broadcast IP address
+ \ h# 2b - 43 Vendor options
+ \ h# 36 - 54 Server IP address
+ " "(01 03 06 0c 0f 11 1c 2b 36)" d# 55 +option
\ Later: Add requested IP address if we know it
\ Later: Add requested IP lease time if we have a preference
- \ Later: Add parameter request list if we care
\ Later: Add maximum message size if we should need to
: use-ip-broadcast ( -- ) broadcast-ip-addr set-dest-ip ;
@@ -288,11 +301,37 @@
-\ For now we'll take the first offer we get.
+\ wanted? is the DHCP offer filter. Many environments have multiple DHCP
+\ servers, some giving incomplete information. You can set wanted? to
+\ require specific characteristics in the offer data.
+\ A better approach would be to collect several offers within a time period
+\ and choose the best among them, stopping early if a "perfect" offer arrives.
\ The default value of wanted? accepts the first DHCPOFFER that is received
defer wanted? ( -- flag ) ' true to wanted?
+\ This filter accepts offers that specify a router
+: router? ( -- flag )
+ 3 find-option dup if nip nip then
+\ This filter accepts offers that specify a name server
+: ns? ( -- flag )
+ 6 find-option dup if nip nip then
+: router+ns? ( -- flag ) router? ns? and ;
+: adaptive-wanted? ( -- flag )
+ backoff case
+ d# 8000 of router+ns? exit endof
+ d# 16000 of router? exit endof
+' adaptive-wanted? to wanted? \ By default, we accept all DHCP offers
\ This filter rejects offers whose siaddr field is empty, (Microsoft's
\ DHCP server doesn't fill in siaddr), since we are hosed if we don't know
\ which server to use.
@@ -304,9 +343,9 @@
" The DHCP 'siaddr' field is empty" .dhcp-msg
-' true to wanted? \ By default, we accept all DHCP offers
\ ' (wanted?) to wanted?
\ Another plausible criterion for choosing a particular offer might be:
\ If a vendor class identifier is supplied, reject offers that do
\ not return that identifier, instead waiting for an offer from a