reading / writing multiple registers

Todd Whitesel toddpw@wrs.com
Fri Aug 27 16:37:00 GMT 1999


> Perhaps there needs to be a heuristic where the number and/or size of
> registers that need to be fetched/stored is compared with the size of
> the entire register set.  If some threshold is reached, the whole set
> would be fetched/stored, otherwise the registers would be handled
> individually.

The problem with register fetching is that the supposedly elegant API
(read a single register or -1 for all of them) forces the rest of the
code to work overtime to spoof around it to improve performance.

While large packets are bad at low speeds, large numbers of synchronous
request/reponse exchanges are bad at ANY speed. This is because the
scheduling on most desktop O/S's tends to shaft a program once it has
blocked on I/O, such that the client program of any RPCish protocol often
waits for the next scheduler tick before it can look at the response,
even if the response arrives much faster.

General heuristics are always going to be less than accurate.
I much prefer two separate avenues of attack:

    1. Identify all the users of the register API who can feasibly compute
	lists of registers they need before requesting any, and provide a
	'deluxe' API call to accomodate them. Eventually this can move down
	into the remote protocol and things get much closer to optimal.
    2. Aggressively use supply_register in back end code where it is clearly
	justified by analyzing real protocol traces. For example on every
	target stop we should request PC/SP/FP or better yet, have the target
	stub volunteer this information. Three registers is probably the most
	you want to volunteer at any point, to avoid making life hard for
	slow serial port users. At 1200 baud, 12 bytes take an extra 1/10th
	of a second to send, which is a few scheduler ticks on many machines.

One concept I pushed hard for at Green Hills, but to my knowledge they never
bought into, was to provide a "create your own jumbo request" packet. The
idea was that instead of hardwiring a single request into each packet, you
let each packet contain a list of requests, a "script" if you will. Do not
allow any programming constructs however. For each packet the target stub
simply walks the packet payload attempting each request; if it succeeds the
response is appended to the response payload, otherwise a failure code is
appended and any further requests in that packet are discarded.

It would be the responsibility of host-side code to only use this form when
it had sufficient smarts to deal with all the possible failure modes. For
things like multiple register transfers and multiple breakpoint operations,
I think it would be quite effective. There's no requirement that everything
exploit it to the absolute fullest for it to provide a benefit.

However, you do have to avoid using the packet length as implicit payload
information... this wasn't a serious problem for the protocol we used at
Green Hills although I think a couple requests would have had needed fixing,
because they omitted an end-of-string null to save a byte.

-- 
Todd Whitesel
toddpw @ wrs.com


More information about the Gdb mailing list