diff options
author | Brent Stapleton <brent.stapleton@ettus.com> | 2017-12-14 10:24:30 -0800 |
---|---|---|
committer | Martin Braun <martin.braun@ettus.com> | 2018-03-14 16:45:45 -0700 |
commit | 86dbaee5b80f203d1a9f28ced0307035d18368fa (patch) | |
tree | 48906c3f61a6b546036909e57c82c15ae4c248d0 | |
parent | 4844f66dccaa71da102b02bba7b8caf8f84a932c (diff) | |
download | uhd-86dbaee5b80f203d1a9f28ced0307035d18368fa.tar.gz uhd-86dbaee5b80f203d1a9f28ced0307035d18368fa.tar.bz2 uhd-86dbaee5b80f203d1a9f28ced0307035d18368fa.zip |
mpm: adding reference counters to UIO
UIO objects now count references on open and close calls. This should
prevent problems with nested function calls that open/close the same
UIO object.
References counts are not atomic -- this is intended for nesting with
statements within the same thread context.
Reviewed-by: Martin Braun <martin.braun@ettus.com>
Reviewed-by: Trung Tran <trung.tran@ettus.com>
-rw-r--r-- | mpm/python/usrp_mpm/sys_utils/uio.py | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/mpm/python/usrp_mpm/sys_utils/uio.py b/mpm/python/usrp_mpm/sys_utils/uio.py index 0a611cc08..2fa99e2b6 100644 --- a/mpm/python/usrp_mpm/sys_utils/uio.py +++ b/mpm/python/usrp_mpm/sys_utils/uio.py @@ -8,8 +8,8 @@ Access to UIO mapped memory. """ import os -from builtins import object from contextlib import contextmanager +from builtins import object import pyudev import usrp_mpm.libpyusrp_periphs as lib from usrp_mpm.mpmlog import get_logger @@ -91,6 +91,23 @@ class UIO(object): """ Provides peek/poke interfaces for uio-mapped memory. + This object will not, by default, open the associated UIO device. To + actually open the device, you have two options: + - Use the instantiation of this class as a context manager (using a `with` + statement), like this: + + >>> with UIO(path="/dev/uio0") as uio0: + >>> uio0.peek32(addr) + >>> uio0.poke32(addr, value) + + - Manually call open() and close(): + + >>> uio0 = UIO(path="/dev/uio0") + >>> uio0.open() + >>> uio0.peek32(addr) + >>> uio0.poke32(addr, value) + >>> uio0.close() + Arguments: label -- Label of the UIO device. The label is set in the device tree overlay @@ -128,21 +145,38 @@ class UIO(object): # Our UIO objects are managed in C++ land, which gives us more granular control over # opening and closing self._uio = lib.types.mmap_regs_iface(self._path, length, offset, self._read_only, False) + # Reference counter for safely __enter__ and __exit__-ing + self._ref_count = 0 def __enter__(self): - self.open() - return self + return self.open() def __exit__(self, exc_type, exc_value, traceback): self.close() return exc_type is None def open(self): - self._uio.open() + """Actually open the UIO device. + + You need to call this before doing peeks and pokes. See also close(). + + If you're using the UIO object as a context manager, it will open the + file automatically. + """ + if self._ref_count == 0: + self._uio.open() + self._ref_count += 1 return self def close(self): - self._uio.close() + """Close a UIO device. + + UIO devices can be problematic with regards to file descriptor leakage, + so it is recommended to close a UIO device when it is no longer needed. + """ + self._ref_count -= 1 + if self._ref_count == 0: + self._uio.close() def peek32(self, addr): """ |