aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrent Stapleton <brent.stapleton@ettus.com>2017-12-14 10:24:30 -0800
committerMartin Braun <martin.braun@ettus.com>2018-03-14 16:45:45 -0700
commit86dbaee5b80f203d1a9f28ced0307035d18368fa (patch)
tree48906c3f61a6b546036909e57c82c15ae4c248d0
parent4844f66dccaa71da102b02bba7b8caf8f84a932c (diff)
downloaduhd-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.py44
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):
"""