mirror of
https://github.com/ARM-software/devlib.git
synced 2025-01-31 02:00:45 +00:00
target: Speedup Target.write_value()
Avoid an execute() by doing the check in the same command. This also allows to return early if the write is fast, and to extend for longer if the write is slow. The speed at which you can observe a write in sysfs depends on the backing kernel handlers, so there is a wide variety of situations. Also, make a more fine grained error detection by allowing the write itself to fail, which can happen when writing invalid values to sysfs.
This commit is contained in:
parent
0c1878786b
commit
e979bafb50
@ -50,7 +50,7 @@ from devlib.platform import Platform
|
||||
from devlib.exception import (DevlibTransientError, TargetStableError,
|
||||
TargetNotRespondingError, TimeoutError,
|
||||
TargetTransientError, KernelConfigKeyError,
|
||||
TargetError, HostError) # pylint: disable=redefined-builtin
|
||||
TargetError, HostError, TargetCalledProcessError) # pylint: disable=redefined-builtin
|
||||
from devlib.utils.ssh import SshConnection
|
||||
from devlib.utils.android import AdbConnection, AndroidProperties, LogcatMonitor, adb_command, adb_disconnect, INTENT_FLAGS
|
||||
from devlib.utils.misc import memoized, isiterable, convert_new_lines, groupby_value
|
||||
@ -848,12 +848,44 @@ class Target(object):
|
||||
|
||||
def write_value(self, path, value, verify=True):
|
||||
value = str(value)
|
||||
self.execute('echo {} > {}'.format(quote(value), quote(path)), check_exit_code=False, as_root=True)
|
||||
|
||||
if verify:
|
||||
output = self.read_value(path)
|
||||
if not output == value:
|
||||
message = 'Could not set the value of {} to "{}" (read "{}")'.format(path, value, output)
|
||||
# Check in a loop for a while since updates to sysfs files can take
|
||||
# some time to be observed, typically when a write triggers a
|
||||
# lengthy kernel-side request, and the read is based on some piece
|
||||
# of state that may take some time to be updated by the write
|
||||
# request, such as hotplugging a CPU.
|
||||
cmd = '''
|
||||
orig=$(cat {path} 2>/dev/null || printf "")
|
||||
printf "%s" {value} > {path} || exit 10
|
||||
if [ {value} != "$orig" ]; then
|
||||
trials=0
|
||||
while [ "$(cat {path} 2>/dev/null)" != {value} ]; do
|
||||
if [ $trials -ge 10 ]; then
|
||||
cat {path}
|
||||
exit 11
|
||||
fi
|
||||
sleep 0.01
|
||||
trials=$((trials + 1))
|
||||
done
|
||||
fi
|
||||
'''
|
||||
else:
|
||||
cmd = '{busybox} printf "%s" {value} > {path}'
|
||||
cmd = cmd.format(busybox=quote(self.busybox), path=quote(path), value=quote(value))
|
||||
|
||||
try:
|
||||
self.execute(cmd, check_exit_code=True, as_root=True)
|
||||
except TargetCalledProcessError as e:
|
||||
if e.returncode == 10:
|
||||
raise TargetStableError('Could not write "{value}" to {path}: {e.output}'.format(
|
||||
value=value, path=path, e=e))
|
||||
elif verify and e.returncode == 11:
|
||||
out = e.output
|
||||
message = 'Could not set the value of {} to "{}" (read "{}")'.format(path, value, out)
|
||||
raise TargetStableError(message)
|
||||
else:
|
||||
raise
|
||||
|
||||
def reset(self):
|
||||
try:
|
||||
|
Loading…
x
Reference in New Issue
Block a user