emdbg.debug.px4.semaphore

 1# Copyright (c) 2023, Auterion AG
 2# SPDX-License-Identifier: BSD-3-Clause
 3
 4from __future__ import annotations
 5from functools import cached_property
 6from dataclasses import dataclass
 7from . import utils
 8from .base import Base
 9
10
11class Semaphore(Base):
12    """
13    Accessor for a NuttX semaphore
14    """
15
16    @dataclass
17    class Holder:
18        task: "emdbg.debug.px4.task.Task"
19        """The task this holder belongs to"""
20        count: int
21        """How many times the task is holding this semaphore"""
22
23    def __init__(self, gdb, sem_ptr: "gdb.Value"):
24        super().__init__(gdb)
25        self._sem = sem_ptr
26        self.count: int = self._sem["semcount"]
27        """Semaphore count, positive if available, 0 if taken, negative if tasks are waiting"""
28
29    @cached_property
30    def flags(self) -> int:
31        """:return: The flags field of the semaphore"""
32        return utils.gdb_getfield(self._sem, "flags", 0b1)
33
34    @cached_property
35    def holders(self) -> list[Holder]:
36        """:return: a list of semaphore holders"""
37        from .task import Task
38
39        #if CONFIG_SEM_PREALLOCHOLDERS == 0
40        if holder := utils.gdb_getfield(self._sem, "holder"):
41            return [self.Holder(Task(self._gdb, holder[0]["htcb"]), int(holder[0]["counts"]))]
42
43        #if CONFIG_SEM_PREALLOCHOLDERS > 0
44        holders = []
45        holder = self._sem["hhead"]
46        while(holder):
47            holders.append(self.Holder(Task(self._gdb, holder["htcb"]), int(holder["counts"])))
48            holder = holder["flink"]
49        return holders
50
51    @property
52    def has_priority_inheritance(self) -> bool:
53        """:return: `True` if the semaphore supports priority inheritance"""
54        return not (self.flags & 0b1)
55
56    def to_string(self) -> str:
57        sc = self.count
58        state = "taken" if sc <= 0 else "available"
59        ostr = f"{state} ({sc}{'i' if self.has_priority_inheritance else ''})"
60        if hstr := [f"{h.count}x {h.task.name}" for h in self.holders]:
61            ostr += f" holders: {', '.join(hstr)}"
62        return ostr
class Semaphore(emdbg.debug.px4.base.Base):
12class Semaphore(Base):
13    """
14    Accessor for a NuttX semaphore
15    """
16
17    @dataclass
18    class Holder:
19        task: "emdbg.debug.px4.task.Task"
20        """The task this holder belongs to"""
21        count: int
22        """How many times the task is holding this semaphore"""
23
24    def __init__(self, gdb, sem_ptr: "gdb.Value"):
25        super().__init__(gdb)
26        self._sem = sem_ptr
27        self.count: int = self._sem["semcount"]
28        """Semaphore count, positive if available, 0 if taken, negative if tasks are waiting"""
29
30    @cached_property
31    def flags(self) -> int:
32        """:return: The flags field of the semaphore"""
33        return utils.gdb_getfield(self._sem, "flags", 0b1)
34
35    @cached_property
36    def holders(self) -> list[Holder]:
37        """:return: a list of semaphore holders"""
38        from .task import Task
39
40        #if CONFIG_SEM_PREALLOCHOLDERS == 0
41        if holder := utils.gdb_getfield(self._sem, "holder"):
42            return [self.Holder(Task(self._gdb, holder[0]["htcb"]), int(holder[0]["counts"]))]
43
44        #if CONFIG_SEM_PREALLOCHOLDERS > 0
45        holders = []
46        holder = self._sem["hhead"]
47        while(holder):
48            holders.append(self.Holder(Task(self._gdb, holder["htcb"]), int(holder["counts"])))
49            holder = holder["flink"]
50        return holders
51
52    @property
53    def has_priority_inheritance(self) -> bool:
54        """:return: `True` if the semaphore supports priority inheritance"""
55        return not (self.flags & 0b1)
56
57    def to_string(self) -> str:
58        sc = self.count
59        state = "taken" if sc <= 0 else "available"
60        ostr = f"{state} ({sc}{'i' if self.has_priority_inheritance else ''})"
61        if hstr := [f"{h.count}x {h.task.name}" for h in self.holders]:
62            ostr += f" holders: {', '.join(hstr)}"
63        return ostr

Accessor for a NuttX semaphore

Semaphore(gdb, sem_ptr: "'gdb.Value'")
24    def __init__(self, gdb, sem_ptr: "gdb.Value"):
25        super().__init__(gdb)
26        self._sem = sem_ptr
27        self.count: int = self._sem["semcount"]
28        """Semaphore count, positive if available, 0 if taken, negative if tasks are waiting"""
count: int

Semaphore count, positive if available, 0 if taken, negative if tasks are waiting

flags: int
30    @cached_property
31    def flags(self) -> int:
32        """:return: The flags field of the semaphore"""
33        return utils.gdb_getfield(self._sem, "flags", 0b1)
Returns

The flags field of the semaphore

holders: list[Semaphore.Holder]
35    @cached_property
36    def holders(self) -> list[Holder]:
37        """:return: a list of semaphore holders"""
38        from .task import Task
39
40        #if CONFIG_SEM_PREALLOCHOLDERS == 0
41        if holder := utils.gdb_getfield(self._sem, "holder"):
42            return [self.Holder(Task(self._gdb, holder[0]["htcb"]), int(holder[0]["counts"]))]
43
44        #if CONFIG_SEM_PREALLOCHOLDERS > 0
45        holders = []
46        holder = self._sem["hhead"]
47        while(holder):
48            holders.append(self.Holder(Task(self._gdb, holder["htcb"]), int(holder["counts"])))
49            holder = holder["flink"]
50        return holders
Returns

a list of semaphore holders

has_priority_inheritance: bool
52    @property
53    def has_priority_inheritance(self) -> bool:
54        """:return: `True` if the semaphore supports priority inheritance"""
55        return not (self.flags & 0b1)
Returns

True if the semaphore supports priority inheritance

def to_string(self) -> str:
57    def to_string(self) -> str:
58        sc = self.count
59        state = "taken" if sc <= 0 else "available"
60        ostr = f"{state} ({sc}{'i' if self.has_priority_inheritance else ''})"
61        if hstr := [f"{h.count}x {h.task.name}" for h in self.holders]:
62            ostr += f" holders: {', '.join(hstr)}"
63        return ostr
@dataclass
class Semaphore.Holder:
17    @dataclass
18    class Holder:
19        task: "emdbg.debug.px4.task.Task"
20        """The task this holder belongs to"""
21        count: int
22        """How many times the task is holding this semaphore"""
Semaphore.Holder(task: emdbg.debug.px4.task.Task, count: int)

The task this holder belongs to

count: int

How many times the task is holding this semaphore