1*43a90889SApple OSS Distributions""" 2*43a90889SApple OSS DistributionsXNU Collection iterators 3*43a90889SApple OSS Distributions""" 4*43a90889SApple OSS Distributionsfrom .cvalue import gettype 5*43a90889SApple OSS Distributionsfrom .standard import xnu_format 6*43a90889SApple OSS Distributions 7*43a90889SApple OSS Distributionsfrom abc import ABCMeta, abstractmethod, abstractproperty 8*43a90889SApple OSS Distributions 9*43a90889SApple OSS Distributions 10*43a90889SApple OSS Distributions# 11*43a90889SApple OSS Distributions# Note to implementers 12*43a90889SApple OSS Distributions# ~~~~~~~~~~~~~~~~~~~~ 13*43a90889SApple OSS Distributions# 14*43a90889SApple OSS Distributions# Iterators must be named iter_* in accordance with typical python API naming 15*43a90889SApple OSS Distributions# 16*43a90889SApple OSS Distributions# The "root" or "head" of the collection must be passed by reference 17*43a90889SApple OSS Distributions# and not by pointer. 18*43a90889SApple OSS Distributions# 19*43a90889SApple OSS Distributions# Returned elements must be references to the element type, 20*43a90889SApple OSS Distributions# and not pointers. 21*43a90889SApple OSS Distributions# 22*43a90889SApple OSS Distributions# Intrusive data types should ask for an "element type" (as an SBType), 23*43a90889SApple OSS Distributions# and a field name or path, and use SBType.xContainerOfTransform 24*43a90889SApple OSS Distributions# to cache the transform to apply for the entire iteration. 25*43a90889SApple OSS Distributions# 26*43a90889SApple OSS Distributions 27*43a90889SApple OSS Distributions 28*43a90889SApple OSS Distributionsdef iter_linked_list(head_value, next_field_or_path, 29*43a90889SApple OSS Distributions first_field_or_path = None): 30*43a90889SApple OSS Distributions """ 31*43a90889SApple OSS Distributions Iterates a NULL-terminated linked list. 32*43a90889SApple OSS Distributions 33*43a90889SApple OSS Distributions Assuming these C types: 34*43a90889SApple OSS Distributions 35*43a90889SApple OSS Distributions struct container { 36*43a90889SApple OSS Distributions struct node *list1_head; 37*43a90889SApple OSS Distributions struct node *list2_head; 38*43a90889SApple OSS Distributions } 39*43a90889SApple OSS Distributions 40*43a90889SApple OSS Distributions struct node { 41*43a90889SApple OSS Distributions struct node *next; 42*43a90889SApple OSS Distributions } 43*43a90889SApple OSS Distributions 44*43a90889SApple OSS Distributions and "v" is an SBValue to a `struct container` type, 45*43a90889SApple OSS Distributions enumerating list1 is: 46*43a90889SApple OSS Distributions 47*43a90889SApple OSS Distributions iter_linked_list(v, 'next', 'list1_head') 48*43a90889SApple OSS Distributions 49*43a90889SApple OSS Distributions if "v" is a `struct node *` directly, then the enumeration 50*43a90889SApple OSS Distributions becomes: 51*43a90889SApple OSS Distributions 52*43a90889SApple OSS Distributions iter_linked_list(v, 'next') 53*43a90889SApple OSS Distributions 54*43a90889SApple OSS Distributions 55*43a90889SApple OSS Distributions @param head_value (SBValue) 56*43a90889SApple OSS Distributions a reference to the list head. 57*43a90889SApple OSS Distributions 58*43a90889SApple OSS Distributions @param next_field_or_path (str) 59*43a90889SApple OSS Distributions The name of (or path to if starting with '.') 60*43a90889SApple OSS Distributions the field linking to the next element. 61*43a90889SApple OSS Distributions 62*43a90889SApple OSS Distributions @param first_field_or_path (str or None) 63*43a90889SApple OSS Distributions The name of (or path to if starting with '.') 64*43a90889SApple OSS Distributions the field from @c head_value holding the pointer 65*43a90889SApple OSS Distributions to the first element of the list. 66*43a90889SApple OSS Distributions """ 67*43a90889SApple OSS Distributions 68*43a90889SApple OSS Distributions if first_field_or_path is None: 69*43a90889SApple OSS Distributions elt = head_value 70*43a90889SApple OSS Distributions elif first_field_or_path[0] == '.': 71*43a90889SApple OSS Distributions elt = head_value.chkGetValueForExpressionPath(first_field_or_path) 72*43a90889SApple OSS Distributions else: 73*43a90889SApple OSS Distributions elt = head_value.chkGetChildMemberWithName(first_field_or_path) 74*43a90889SApple OSS Distributions 75*43a90889SApple OSS Distributions if next_field_or_path[0] == '.': 76*43a90889SApple OSS Distributions while elt.GetValueAsAddress(): 77*43a90889SApple OSS Distributions elt = elt.Dereference() 78*43a90889SApple OSS Distributions yield elt 79*43a90889SApple OSS Distributions elt = elt.chkGetValueForExpressionPath(next_field_or_path) 80*43a90889SApple OSS Distributions else: 81*43a90889SApple OSS Distributions while elt.GetValueAsAddress(): 82*43a90889SApple OSS Distributions elt = elt.Dereference() 83*43a90889SApple OSS Distributions yield elt 84*43a90889SApple OSS Distributions elt = elt.chkGetChildMemberWithName(next_field_or_path) 85*43a90889SApple OSS Distributions 86*43a90889SApple OSS Distributions 87*43a90889SApple OSS Distributionsdef iter_queue_entries(head_value, elt_type, field_name_or_path, backwards=False): 88*43a90889SApple OSS Distributions """ 89*43a90889SApple OSS Distributions Iterate over a queue of entries (<kern/queue.h> method 1) 90*43a90889SApple OSS Distributions 91*43a90889SApple OSS Distributions @param head_value (SBValue) 92*43a90889SApple OSS Distributions a reference to the list head (queue_head_t) 93*43a90889SApple OSS Distributions 94*43a90889SApple OSS Distributions @param elt_type (SBType) 95*43a90889SApple OSS Distributions The type of the elements on the chain 96*43a90889SApple OSS Distributions 97*43a90889SApple OSS Distributions @param field_name_or_path (str) 98*43a90889SApple OSS Distributions The name of (or path to if starting with '.') the field 99*43a90889SApple OSS Distributions containing the struct mpsc_queue_chain linkage. 100*43a90889SApple OSS Distributions 101*43a90889SApple OSS Distributions @param backwards (bool) 102*43a90889SApple OSS Distributions Whether the walk is forward or backwards 103*43a90889SApple OSS Distributions """ 104*43a90889SApple OSS Distributions 105*43a90889SApple OSS Distributions stop = head_value.GetLoadAddress() 106*43a90889SApple OSS Distributions elt = head_value 107*43a90889SApple OSS Distributions key = 'prev' if backwards else 'next' 108*43a90889SApple OSS Distributions 109*43a90889SApple OSS Distributions transform = elt_type.xContainerOfTransform(field_name_or_path) 110*43a90889SApple OSS Distributions 111*43a90889SApple OSS Distributions while True: 112*43a90889SApple OSS Distributions elt = elt.chkGetChildMemberWithName(key) 113*43a90889SApple OSS Distributions addr = elt.GetValueAsAddress() 114*43a90889SApple OSS Distributions if addr == 0 or addr == stop: 115*43a90889SApple OSS Distributions break 116*43a90889SApple OSS Distributions elt = elt.Dereference() 117*43a90889SApple OSS Distributions yield transform(elt) 118*43a90889SApple OSS Distributions 119*43a90889SApple OSS Distributions 120*43a90889SApple OSS Distributionsdef iter_queue(head_value, elt_type, field_name_or_path, backwards=False, unpack=None): 121*43a90889SApple OSS Distributions """ 122*43a90889SApple OSS Distributions Iterate over queue of elements (<kern/queue.h> method 2) 123*43a90889SApple OSS Distributions 124*43a90889SApple OSS Distributions @param head_value (SBValue) 125*43a90889SApple OSS Distributions A reference to the list head (queue_head_t) 126*43a90889SApple OSS Distributions 127*43a90889SApple OSS Distributions @param elt_type (SBType) 128*43a90889SApple OSS Distributions The type of the elements on the chain 129*43a90889SApple OSS Distributions 130*43a90889SApple OSS Distributions @param field_name_or_path (str) 131*43a90889SApple OSS Distributions The name of (or path to if starting with '.') the field 132*43a90889SApple OSS Distributions containing the struct mpsc_queue_chain linkage. 133*43a90889SApple OSS Distributions 134*43a90889SApple OSS Distributions @param backwards (bool) 135*43a90889SApple OSS Distributions Whether the walk is forward or backwards 136*43a90889SApple OSS Distributions 137*43a90889SApple OSS Distributions @param unpack (Function or None) 138*43a90889SApple OSS Distributions A function to unpack the pointer or None. 139*43a90889SApple OSS Distributions """ 140*43a90889SApple OSS Distributions 141*43a90889SApple OSS Distributions stop = head_value.GetLoadAddress() 142*43a90889SApple OSS Distributions elt = head_value 143*43a90889SApple OSS Distributions key = '.prev' if backwards else '.next' 144*43a90889SApple OSS Distributions addr = elt.xGetScalarByPath(key) 145*43a90889SApple OSS Distributions if field_name_or_path[0] == '.': 146*43a90889SApple OSS Distributions path = field_name_or_path + key 147*43a90889SApple OSS Distributions else: 148*43a90889SApple OSS Distributions path = "." + field_name_or_path + key 149*43a90889SApple OSS Distributions 150*43a90889SApple OSS Distributions while True: 151*43a90889SApple OSS Distributions if unpack is not None: 152*43a90889SApple OSS Distributions addr = unpack(addr) 153*43a90889SApple OSS Distributions if addr == 0 or addr == stop: 154*43a90889SApple OSS Distributions break 155*43a90889SApple OSS Distributions 156*43a90889SApple OSS Distributions elt = elt.xCreateValueFromAddress('element', addr, elt_type) 157*43a90889SApple OSS Distributions addr = elt.xGetScalarByPath(path) 158*43a90889SApple OSS Distributions yield elt 159*43a90889SApple OSS Distributions 160*43a90889SApple OSS Distributions 161*43a90889SApple OSS Distributionsdef iter_circle_queue(head_value, elt_type, field_name_or_path, backwards=False): 162*43a90889SApple OSS Distributions """ 163*43a90889SApple OSS Distributions Iterate over a queue of entries (<kern/circle_queue.h>) 164*43a90889SApple OSS Distributions 165*43a90889SApple OSS Distributions @param head_value (SBValue) 166*43a90889SApple OSS Distributions a reference to the list head (circle_queue_head_t) 167*43a90889SApple OSS Distributions 168*43a90889SApple OSS Distributions @param elt_type (SBType) 169*43a90889SApple OSS Distributions The type of the elements on the chain 170*43a90889SApple OSS Distributions 171*43a90889SApple OSS Distributions @param field_name_or_path (str) 172*43a90889SApple OSS Distributions The name of (or path to if starting with '.') the field 173*43a90889SApple OSS Distributions containing the struct mpsc_queue_chain linkage. 174*43a90889SApple OSS Distributions 175*43a90889SApple OSS Distributions @param backwards (bool) 176*43a90889SApple OSS Distributions Whether the walk is forward or backwards 177*43a90889SApple OSS Distributions """ 178*43a90889SApple OSS Distributions 179*43a90889SApple OSS Distributions elt = head_value.chkGetChildMemberWithName('head') 180*43a90889SApple OSS Distributions stop = elt.GetValueAsAddress() 181*43a90889SApple OSS Distributions key = 'prev' if backwards else 'next' 182*43a90889SApple OSS Distributions 183*43a90889SApple OSS Distributions transform = elt_type.xContainerOfTransform(field_name_or_path) 184*43a90889SApple OSS Distributions 185*43a90889SApple OSS Distributions if stop: 186*43a90889SApple OSS Distributions if backwards: 187*43a90889SApple OSS Distributions elt = elt.chkGetValueForExpressionPath('->prev') 188*43a90889SApple OSS Distributions stop = elt.GetValueAsAddress() 189*43a90889SApple OSS Distributions 190*43a90889SApple OSS Distributions while True: 191*43a90889SApple OSS Distributions elt = elt.Dereference() 192*43a90889SApple OSS Distributions yield transform(elt) 193*43a90889SApple OSS Distributions 194*43a90889SApple OSS Distributions elt = elt.chkGetChildMemberWithName(key) 195*43a90889SApple OSS Distributions addr = elt.GetValueAsAddress() 196*43a90889SApple OSS Distributions if addr == 0 or addr == stop: 197*43a90889SApple OSS Distributions break 198*43a90889SApple OSS Distributions 199*43a90889SApple OSS Distributions 200*43a90889SApple OSS Distributionsdef iter_mpsc_queue(head_value, elt_type, field_name_or_path): 201*43a90889SApple OSS Distributions """ 202*43a90889SApple OSS Distributions Iterates a struct mpsc_queue_head 203*43a90889SApple OSS Distributions 204*43a90889SApple OSS Distributions @param head_value (SBValue) 205*43a90889SApple OSS Distributions A struct mpsc_queue_head value. 206*43a90889SApple OSS Distributions 207*43a90889SApple OSS Distributions @param elt_type (SBType) 208*43a90889SApple OSS Distributions The type of the elements on the chain. 209*43a90889SApple OSS Distributions 210*43a90889SApple OSS Distributions @param field_name_or_path (str) 211*43a90889SApple OSS Distributions The name of (or path to if starting with '.') the field 212*43a90889SApple OSS Distributions containing the struct mpsc_queue_chain linkage. 213*43a90889SApple OSS Distributions 214*43a90889SApple OSS Distributions @returns (generator) 215*43a90889SApple OSS Distributions An iterator for the MPSC queue. 216*43a90889SApple OSS Distributions """ 217*43a90889SApple OSS Distributions 218*43a90889SApple OSS Distributions transform = elt_type.xContainerOfTransform(field_name_or_path) 219*43a90889SApple OSS Distributions 220*43a90889SApple OSS Distributions return (transform(e) for e in iter_linked_list( 221*43a90889SApple OSS Distributions head_value, 'mpqc_next', '.mpqh_head.mpqc_next' 222*43a90889SApple OSS Distributions )) 223*43a90889SApple OSS Distributions 224*43a90889SApple OSS Distributions 225*43a90889SApple OSS Distributionsclass iter_priority_queue(object): 226*43a90889SApple OSS Distributions """ 227*43a90889SApple OSS Distributions Iterates any of the priority queues from <kern/priority_queue.h> 228*43a90889SApple OSS Distributions 229*43a90889SApple OSS Distributions @param head_value (SBValue) 230*43a90889SApple OSS Distributions A struct priority_queue* value. 231*43a90889SApple OSS Distributions 232*43a90889SApple OSS Distributions @param elt_type (SBType) 233*43a90889SApple OSS Distributions The type of the elements on the chain. 234*43a90889SApple OSS Distributions 235*43a90889SApple OSS Distributions @param field_name_or_path (str) 236*43a90889SApple OSS Distributions The name of (or path to if starting with '.') the field 237*43a90889SApple OSS Distributions containing the struct priority_queue_entry* linkage. 238*43a90889SApple OSS Distributions 239*43a90889SApple OSS Distributions @returns (generator) 240*43a90889SApple OSS Distributions An iterator for the priority queue. 241*43a90889SApple OSS Distributions """ 242*43a90889SApple OSS Distributions 243*43a90889SApple OSS Distributions def __init__(self, head_value, elt_type, field_name_or_path): 244*43a90889SApple OSS Distributions self.transform = elt_type.xContainerOfTransform(field_name_or_path) 245*43a90889SApple OSS Distributions 246*43a90889SApple OSS Distributions self.gen = iter_linked_list(head_value, 'next', 'pq_root') 247*43a90889SApple OSS Distributions self.queue = [] 248*43a90889SApple OSS Distributions 249*43a90889SApple OSS Distributions def __iter__(self): 250*43a90889SApple OSS Distributions return self 251*43a90889SApple OSS Distributions 252*43a90889SApple OSS Distributions def __next__(self): 253*43a90889SApple OSS Distributions queue = self.queue 254*43a90889SApple OSS Distributions elt = next(self.gen, None) 255*43a90889SApple OSS Distributions 256*43a90889SApple OSS Distributions if elt is None: 257*43a90889SApple OSS Distributions if not len(queue): 258*43a90889SApple OSS Distributions raise StopIteration 259*43a90889SApple OSS Distributions elt = queue.pop() 260*43a90889SApple OSS Distributions self.gen = iter_linked_list(elt, 'next', 'next') 261*43a90889SApple OSS Distributions 262*43a90889SApple OSS Distributions addr = elt.xGetScalarByName('child') 263*43a90889SApple OSS Distributions if addr: 264*43a90889SApple OSS Distributions queue.append(elt.xCreateValueFromAddress( 265*43a90889SApple OSS Distributions None, addr & 0xffffffffffffffff, elt.GetType())) 266*43a90889SApple OSS Distributions 267*43a90889SApple OSS Distributions return self.transform(elt) 268*43a90889SApple OSS Distributions 269*43a90889SApple OSS Distributionsdef iter_SLIST_HEAD(head_value, link_field): 270*43a90889SApple OSS Distributions """ Specialized version of iter_linked_list() for <sys/queue.h> SLIST_HEAD """ 271*43a90889SApple OSS Distributions 272*43a90889SApple OSS Distributions next_path = ".{}.sle_next".format(link_field) 273*43a90889SApple OSS Distributions return (e for e in iter_linked_list(head_value, next_path, "slh_first")) 274*43a90889SApple OSS Distributions 275*43a90889SApple OSS Distributionsdef iter_LIST_HEAD(head_value, link_field): 276*43a90889SApple OSS Distributions """ Specialized version of iter_linked_list() for <sys/queue.h> LIST_HEAD """ 277*43a90889SApple OSS Distributions 278*43a90889SApple OSS Distributions next_path = ".{}.le_next".format(link_field) 279*43a90889SApple OSS Distributions return (e for e in iter_linked_list(head_value, next_path, "lh_first")) 280*43a90889SApple OSS Distributions 281*43a90889SApple OSS Distributionsdef iter_STAILQ_HEAD(head_value, link_field): 282*43a90889SApple OSS Distributions """ Specialized version of iter_linked_list() for <sys/queue.h> STAILQ_HEAD """ 283*43a90889SApple OSS Distributions 284*43a90889SApple OSS Distributions next_path = ".{}.stqe_next".format(link_field) 285*43a90889SApple OSS Distributions return (e for e in iter_linked_list(head_value, next_path, "stqh_first")) 286*43a90889SApple OSS Distributions 287*43a90889SApple OSS Distributionsdef iter_TAILQ_HEAD(head_value, link_field): 288*43a90889SApple OSS Distributions """ Specialized version of iter_linked_list() for <sys/queue.h> TAILQ_HEAD """ 289*43a90889SApple OSS Distributions 290*43a90889SApple OSS Distributions next_path = ".{}.tqe_next".format(link_field) 291*43a90889SApple OSS Distributions return (e for e in iter_linked_list(head_value, next_path, "tqh_first")) 292*43a90889SApple OSS Distributions 293*43a90889SApple OSS Distributionsdef iter_SYS_QUEUE_HEAD(head_value, link_field): 294*43a90889SApple OSS Distributions """ Specialized version of iter_linked_list() for any <sys/queue> *_HEAD """ 295*43a90889SApple OSS Distributions 296*43a90889SApple OSS Distributions field = head_value.rawGetType().GetFieldAtIndex(0).GetName() 297*43a90889SApple OSS Distributions next_path = ".{}.{}e_next".format(link_field, field.partition('_')[0]) 298*43a90889SApple OSS Distributions return (e for e in iter_linked_list(head_value, next_path, field)) 299*43a90889SApple OSS Distributions 300*43a90889SApple OSS Distributions 301*43a90889SApple OSS Distributionsclass RB_HEAD(object): 302*43a90889SApple OSS Distributions """ 303*43a90889SApple OSS Distributions Class providing utilities to manipulate a collection made with RB_HEAD() 304*43a90889SApple OSS Distributions """ 305*43a90889SApple OSS Distributions 306*43a90889SApple OSS Distributions def __init__(self, rbh_root_value, link_field, cmp): 307*43a90889SApple OSS Distributions """ 308*43a90889SApple OSS Distributions Create an rb-tree wrapper 309*43a90889SApple OSS Distributions 310*43a90889SApple OSS Distributions @param rbh_root_value (SBValue) 311*43a90889SApple OSS Distributions A value to an RB_HEAD() field 312*43a90889SApple OSS Distributions 313*43a90889SApple OSS Distributions @param link_field (str) 314*43a90889SApple OSS Distributions The name of the RB_ENTRY() field in the elements 315*43a90889SApple OSS Distributions 316*43a90889SApple OSS Distributions @param cmp (function) 317*43a90889SApple OSS Distributions The comparison function between a linked element, 318*43a90889SApple OSS Distributions and a key 319*43a90889SApple OSS Distributions """ 320*43a90889SApple OSS Distributions 321*43a90889SApple OSS Distributions self.root_sbv = rbh_root_value.chkGetChildMemberWithName('rbh_root') 322*43a90889SApple OSS Distributions self.field = link_field 323*43a90889SApple OSS Distributions self.cmp = cmp 324*43a90889SApple OSS Distributions self.etype = self.root_sbv.GetType().GetPointeeType() 325*43a90889SApple OSS Distributions 326*43a90889SApple OSS Distributions def _parent(self, elt): 327*43a90889SApple OSS Distributions RB_COLOR_MASK = 0x1 328*43a90889SApple OSS Distributions 329*43a90889SApple OSS Distributions path = "." + self.field + ".rbe_parent" 330*43a90889SApple OSS Distributions parent = elt.chkGetValueForExpressionPath(path) 331*43a90889SApple OSS Distributions paddr = parent.GetValueAsAddress() 332*43a90889SApple OSS Distributions 333*43a90889SApple OSS Distributions if paddr == 0: 334*43a90889SApple OSS Distributions return None, 0 335*43a90889SApple OSS Distributions 336*43a90889SApple OSS Distributions if paddr & RB_COLOR_MASK == 0: 337*43a90889SApple OSS Distributions return parent.Dereference(), paddr 338*43a90889SApple OSS Distributions 339*43a90889SApple OSS Distributions paddr &= ~RB_COLOR_MASK 340*43a90889SApple OSS Distributions return parent.xCreateValueFromAddress(None, paddr, self.etype), paddr 341*43a90889SApple OSS Distributions 342*43a90889SApple OSS Distributions def _sibling(self, elt, rbe_left, rbe_right): 343*43a90889SApple OSS Distributions 344*43a90889SApple OSS Distributions field = self.field 345*43a90889SApple OSS Distributions lpath = "." + field + rbe_left 346*43a90889SApple OSS Distributions rpath = "." + field + rbe_right 347*43a90889SApple OSS Distributions 348*43a90889SApple OSS Distributions e_r = elt.chkGetValueForExpressionPath(rpath) 349*43a90889SApple OSS Distributions if e_r.GetValueAsAddress(): 350*43a90889SApple OSS Distributions # 351*43a90889SApple OSS Distributions # IF (RB_RIGHT(elm, field)) { 352*43a90889SApple OSS Distributions # elm = RB_RIGHT(elm, field); 353*43a90889SApple OSS Distributions # while (RB_LEFT(elm, field)) 354*43a90889SApple OSS Distributions # elm = RB_LEFT(elm, field); 355*43a90889SApple OSS Distributions # 356*43a90889SApple OSS Distributions 357*43a90889SApple OSS Distributions path = "->" + field + rbe_left 358*43a90889SApple OSS Distributions res = e_r 359*43a90889SApple OSS Distributions e_l = res.chkGetValueForExpressionPath(path) 360*43a90889SApple OSS Distributions while e_l.GetValueAsAddress(): 361*43a90889SApple OSS Distributions res = e_l 362*43a90889SApple OSS Distributions e_l = res.chkGetValueForExpressionPath(path) 363*43a90889SApple OSS Distributions 364*43a90889SApple OSS Distributions return res.Dereference() 365*43a90889SApple OSS Distributions 366*43a90889SApple OSS Distributions eaddr = elt.GetLoadAddress() 367*43a90889SApple OSS Distributions e_p, paddr = self._parent(elt) 368*43a90889SApple OSS Distributions 369*43a90889SApple OSS Distributions if paddr: 370*43a90889SApple OSS Distributions # 371*43a90889SApple OSS Distributions # IF (RB_GETPARENT(elm) && 372*43a90889SApple OSS Distributions # (elm == RB_LEFT(RB_GETPARENT(elm), field))) 373*43a90889SApple OSS Distributions # elm = RB_GETPARENT(elm) 374*43a90889SApple OSS Distributions # 375*43a90889SApple OSS Distributions 376*43a90889SApple OSS Distributions if e_p.xGetScalarByPath(lpath) == eaddr: 377*43a90889SApple OSS Distributions return e_p 378*43a90889SApple OSS Distributions 379*43a90889SApple OSS Distributions # 380*43a90889SApple OSS Distributions # WHILE (RB_GETPARENT(elm) && 381*43a90889SApple OSS Distributions # (elm == RB_RIGHT(RB_GETPARENT(elm), field))) 382*43a90889SApple OSS Distributions # elm = RB_GETPARENT(elm); 383*43a90889SApple OSS Distributions # elm = RB_GETPARENT(elm); 384*43a90889SApple OSS Distributions # 385*43a90889SApple OSS Distributions 386*43a90889SApple OSS Distributions while paddr: 387*43a90889SApple OSS Distributions if e_p.xGetScalarByPath(rpath) != eaddr: 388*43a90889SApple OSS Distributions return e_p 389*43a90889SApple OSS Distributions 390*43a90889SApple OSS Distributions eaddr = paddr 391*43a90889SApple OSS Distributions e_p, paddr = self._parent(e_p) 392*43a90889SApple OSS Distributions 393*43a90889SApple OSS Distributions return None 394*43a90889SApple OSS Distributions 395*43a90889SApple OSS Distributions def _find(self, key): 396*43a90889SApple OSS Distributions elt = self.root_sbv 397*43a90889SApple OSS Distributions f = self.field 398*43a90889SApple OSS Distributions le = None 399*43a90889SApple OSS Distributions ge = None 400*43a90889SApple OSS Distributions 401*43a90889SApple OSS Distributions while elt.GetValueAsAddress(): 402*43a90889SApple OSS Distributions elt = elt.Dereference() 403*43a90889SApple OSS Distributions rc = self.cmp(elt, key) 404*43a90889SApple OSS Distributions if rc == 0: 405*43a90889SApple OSS Distributions return elt, elt, elt 406*43a90889SApple OSS Distributions 407*43a90889SApple OSS Distributions if rc < 0: 408*43a90889SApple OSS Distributions ge = elt 409*43a90889SApple OSS Distributions elt = elt.chkGetValueForExpressionPath("->" + f + ".rbe_left") 410*43a90889SApple OSS Distributions else: 411*43a90889SApple OSS Distributions le = elt 412*43a90889SApple OSS Distributions elt = elt.chkGetValueForExpressionPath("->" + f + ".rbe_right") 413*43a90889SApple OSS Distributions 414*43a90889SApple OSS Distributions return le, None, ge 415*43a90889SApple OSS Distributions 416*43a90889SApple OSS Distributions def _minmax(self, direction): 417*43a90889SApple OSS Distributions """ Returns the first element in the tree """ 418*43a90889SApple OSS Distributions 419*43a90889SApple OSS Distributions elt = self.root_sbv 420*43a90889SApple OSS Distributions res = None 421*43a90889SApple OSS Distributions path = "->" + self.field + direction 422*43a90889SApple OSS Distributions 423*43a90889SApple OSS Distributions while elt.GetValueAsAddress(): 424*43a90889SApple OSS Distributions res = elt 425*43a90889SApple OSS Distributions elt = elt.chkGetValueForExpressionPath(path) 426*43a90889SApple OSS Distributions 427*43a90889SApple OSS Distributions return res.Dereference() if res is not None else None 428*43a90889SApple OSS Distributions 429*43a90889SApple OSS Distributions def find_lt(self, key): 430*43a90889SApple OSS Distributions """ Find the element smaller than the specified key """ 431*43a90889SApple OSS Distributions 432*43a90889SApple OSS Distributions elt, _, _ = self._find(key) 433*43a90889SApple OSS Distributions return self.prev(elt) if elt is not None else None 434*43a90889SApple OSS Distributions 435*43a90889SApple OSS Distributions def find_le(self, key): 436*43a90889SApple OSS Distributions """ Find the element smaller or equal to the specified key """ 437*43a90889SApple OSS Distributions 438*43a90889SApple OSS Distributions elt, _, _ = self._find(key) 439*43a90889SApple OSS Distributions return elt 440*43a90889SApple OSS Distributions 441*43a90889SApple OSS Distributions def find(self, key): 442*43a90889SApple OSS Distributions """ Find the element with the specified key """ 443*43a90889SApple OSS Distributions 444*43a90889SApple OSS Distributions _, elt, _ = self._find(key) 445*43a90889SApple OSS Distributions return elt 446*43a90889SApple OSS Distributions 447*43a90889SApple OSS Distributions def find_ge(self, key): 448*43a90889SApple OSS Distributions """ Find the element greater or equal to the specified key """ 449*43a90889SApple OSS Distributions 450*43a90889SApple OSS Distributions _, _, elt = self._find(key) 451*43a90889SApple OSS Distributions return elt 452*43a90889SApple OSS Distributions 453*43a90889SApple OSS Distributions def find_gt(self, key): 454*43a90889SApple OSS Distributions """ Find the element greater than the specified key """ 455*43a90889SApple OSS Distributions 456*43a90889SApple OSS Distributions _, _, elt = self._find(key) 457*43a90889SApple OSS Distributions return self.next(elt.Dereference()) if elt is not None else None 458*43a90889SApple OSS Distributions 459*43a90889SApple OSS Distributions def first(self): 460*43a90889SApple OSS Distributions """ Returns the first element in the tree """ 461*43a90889SApple OSS Distributions 462*43a90889SApple OSS Distributions return self._minmax(".rbe_left") 463*43a90889SApple OSS Distributions 464*43a90889SApple OSS Distributions def last(self): 465*43a90889SApple OSS Distributions """ Returns the last element in the tree """ 466*43a90889SApple OSS Distributions 467*43a90889SApple OSS Distributions return self._minmax(".rbe_right") 468*43a90889SApple OSS Distributions 469*43a90889SApple OSS Distributions def next(self, elt): 470*43a90889SApple OSS Distributions """ Returns the next element in rbtree order or None """ 471*43a90889SApple OSS Distributions 472*43a90889SApple OSS Distributions return self._sibling(elt, ".rbe_left", ".rbe_right") 473*43a90889SApple OSS Distributions 474*43a90889SApple OSS Distributions def prev(self, elt): 475*43a90889SApple OSS Distributions """ Returns the next element in rbtree order or None """ 476*43a90889SApple OSS Distributions 477*43a90889SApple OSS Distributions return self._sibling(elt, ".rbe_right", ".rbe_left") 478*43a90889SApple OSS Distributions 479*43a90889SApple OSS Distributions def iter(self, min_key=None, max_key=None): 480*43a90889SApple OSS Distributions """ 481*43a90889SApple OSS Distributions Iterates all elements in this red-black tree 482*43a90889SApple OSS Distributions with min_key <= key < max_key 483*43a90889SApple OSS Distributions """ 484*43a90889SApple OSS Distributions 485*43a90889SApple OSS Distributions e = self.first() if min_key is None else self.find_ge(min_key) 486*43a90889SApple OSS Distributions 487*43a90889SApple OSS Distributions if max_key is None: 488*43a90889SApple OSS Distributions while e is not None: 489*43a90889SApple OSS Distributions yield e 490*43a90889SApple OSS Distributions e = self.next(e) 491*43a90889SApple OSS Distributions else: 492*43a90889SApple OSS Distributions cmp = self.cmp 493*43a90889SApple OSS Distributions while e is not None and cmp(e, max_key) >= 0: 494*43a90889SApple OSS Distributions yield e 495*43a90889SApple OSS Distributions e = self.next(e) 496*43a90889SApple OSS Distributions 497*43a90889SApple OSS Distributions def __iter__(self): 498*43a90889SApple OSS Distributions return self.iter() 499*43a90889SApple OSS Distributions 500*43a90889SApple OSS Distributions 501*43a90889SApple OSS Distributionsdef iter_RB_HEAD(rbh_root_value, link_field): 502*43a90889SApple OSS Distributions """ Conveniency wrapper for RB_HEAD iteration """ 503*43a90889SApple OSS Distributions 504*43a90889SApple OSS Distributions return RB_HEAD(rbh_root_value, link_field, None).iter() 505*43a90889SApple OSS Distributions 506*43a90889SApple OSS Distributions 507*43a90889SApple OSS Distributionsdef iter_smr_queue(head_value, elt_type, field_name_or_path): 508*43a90889SApple OSS Distributions """ 509*43a90889SApple OSS Distributions Iterate over an SMR queue of entries (<kern/smr.h>) 510*43a90889SApple OSS Distributions 511*43a90889SApple OSS Distributions @param head_value (SBValue) 512*43a90889SApple OSS Distributions a reference to the list head (struct smrq_*_head) 513*43a90889SApple OSS Distributions 514*43a90889SApple OSS Distributions @param elt_type (SBType) 515*43a90889SApple OSS Distributions The type of the elements on the chain 516*43a90889SApple OSS Distributions 517*43a90889SApple OSS Distributions @param field_name_or_path (str) 518*43a90889SApple OSS Distributions The name of (or path to if starting with '.') the field 519*43a90889SApple OSS Distributions containing the struct mpsc_queue_chain linkage. 520*43a90889SApple OSS Distributions """ 521*43a90889SApple OSS Distributions 522*43a90889SApple OSS Distributions transform = elt_type.xContainerOfTransform(field_name_or_path) 523*43a90889SApple OSS Distributions 524*43a90889SApple OSS Distributions return (transform(e) for e in iter_linked_list( 525*43a90889SApple OSS Distributions head_value, '.next.__smr_ptr', '.first.__smr_ptr' 526*43a90889SApple OSS Distributions )) 527*43a90889SApple OSS Distributions 528*43a90889SApple OSS Distributionsclass _Hash(object, metaclass=ABCMeta): 529*43a90889SApple OSS Distributions @abstractproperty 530*43a90889SApple OSS Distributions def buckets(self): 531*43a90889SApple OSS Distributions """ 532*43a90889SApple OSS Distributions Returns the number of buckets in the hash table 533*43a90889SApple OSS Distributions """ 534*43a90889SApple OSS Distributions pass 535*43a90889SApple OSS Distributions 536*43a90889SApple OSS Distributions @abstractproperty 537*43a90889SApple OSS Distributions def count(self): 538*43a90889SApple OSS Distributions """ 539*43a90889SApple OSS Distributions Returns the number of elements in the hash table 540*43a90889SApple OSS Distributions """ 541*43a90889SApple OSS Distributions pass 542*43a90889SApple OSS Distributions 543*43a90889SApple OSS Distributions @abstractproperty 544*43a90889SApple OSS Distributions def rehashing(self): 545*43a90889SApple OSS Distributions """ 546*43a90889SApple OSS Distributions Returns whether the hash is currently rehashing 547*43a90889SApple OSS Distributions """ 548*43a90889SApple OSS Distributions pass 549*43a90889SApple OSS Distributions 550*43a90889SApple OSS Distributions @abstractmethod 551*43a90889SApple OSS Distributions def iter(self, detailed=False): 552*43a90889SApple OSS Distributions """ 553*43a90889SApple OSS Distributions @param detailed (bool) 554*43a90889SApple OSS Distributions whether to enumerate just elements, or show bucket info too 555*43a90889SApple OSS Distributions when bucket info is requested, enumeration returns a tuple of: 556*43a90889SApple OSS Distributions (0, bucket, index_in_bucket, element) 557*43a90889SApple OSS Distributions """ 558*43a90889SApple OSS Distributions pass 559*43a90889SApple OSS Distributions 560*43a90889SApple OSS Distributions def __iter__(self): 561*43a90889SApple OSS Distributions return self.iter() 562*43a90889SApple OSS Distributions 563*43a90889SApple OSS Distributions def describe(self): 564*43a90889SApple OSS Distributions fmt = ( 565*43a90889SApple OSS Distributions "Hash table info\n" 566*43a90889SApple OSS Distributions " address : {1:#x}\n" 567*43a90889SApple OSS Distributions " element count : {0.count}\n" 568*43a90889SApple OSS Distributions " bucket count : {0.buckets}\n" 569*43a90889SApple OSS Distributions " rehashing : {0.rehashing}" 570*43a90889SApple OSS Distributions ) 571*43a90889SApple OSS Distributions print(xnu_format(fmt, self, self.hash_value.GetLoadAddress())) 572*43a90889SApple OSS Distributions 573*43a90889SApple OSS Distributions if self.rehashing: 574*43a90889SApple OSS Distributions print() 575*43a90889SApple OSS Distributions return 576*43a90889SApple OSS Distributions 577*43a90889SApple OSS Distributions b_len = {} 578*43a90889SApple OSS Distributions for _, b_idx, e_idx, _ in self.iter(detailed=True): 579*43a90889SApple OSS Distributions b_len[b_idx] = e_idx + 1 580*43a90889SApple OSS Distributions 581*43a90889SApple OSS Distributions stats = {i: 0 for i in range(max(b_len.values()) + 1) } 582*43a90889SApple OSS Distributions for v in b_len.values(): 583*43a90889SApple OSS Distributions stats[v] += 1 584*43a90889SApple OSS Distributions stats[0] = self.buckets - len(b_len) 585*43a90889SApple OSS Distributions 586*43a90889SApple OSS Distributions fmt = ( 587*43a90889SApple OSS Distributions " histogram :\n" 588*43a90889SApple OSS Distributions " {:>4} {:>6} {:>6} {:>6} {:>5}" 589*43a90889SApple OSS Distributions ) 590*43a90889SApple OSS Distributions print(xnu_format(fmt, "size", "count", "(cum)", "%", "(cum)")) 591*43a90889SApple OSS Distributions 592*43a90889SApple OSS Distributions fmt = " {:>4,d} {:>6,d} {:>6,d} {:>6.1%} {:>5.0%}" 593*43a90889SApple OSS Distributions tot = 0 594*43a90889SApple OSS Distributions for sz, n in stats.items(): 595*43a90889SApple OSS Distributions tot += n 596*43a90889SApple OSS Distributions print(xnu_format(fmt, sz, n, tot, n / self.buckets, tot / self.buckets)) 597*43a90889SApple OSS Distributions 598*43a90889SApple OSS Distributions 599*43a90889SApple OSS Distributionsclass SMRHash(_Hash): 600*43a90889SApple OSS Distributions """ 601*43a90889SApple OSS Distributions Class providing utilities to manipulate SMR hash tables 602*43a90889SApple OSS Distributions """ 603*43a90889SApple OSS Distributions 604*43a90889SApple OSS Distributions def __init__(self, hash_value, traits_value): 605*43a90889SApple OSS Distributions """ 606*43a90889SApple OSS Distributions Create an smr hash table iterator 607*43a90889SApple OSS Distributions 608*43a90889SApple OSS Distributions @param hash_value (SBValue) 609*43a90889SApple OSS Distributions a reference to a struct smr_hash instance. 610*43a90889SApple OSS Distributions 611*43a90889SApple OSS Distributions @param traits_value (SBValue) 612*43a90889SApple OSS Distributions a reference to the traits for this hash table 613*43a90889SApple OSS Distributions """ 614*43a90889SApple OSS Distributions super().__init__() 615*43a90889SApple OSS Distributions self.hash_value = hash_value 616*43a90889SApple OSS Distributions self.traits_value = traits_value 617*43a90889SApple OSS Distributions 618*43a90889SApple OSS Distributions @property 619*43a90889SApple OSS Distributions def buckets(self): 620*43a90889SApple OSS Distributions hash_arr = self.hash_value.xGetScalarByName('smrh_array') 621*43a90889SApple OSS Distributions return 1 << (64 - ((hash_arr >> 48) & 0x00ff)) 622*43a90889SApple OSS Distributions 623*43a90889SApple OSS Distributions @property 624*43a90889SApple OSS Distributions def count(self): 625*43a90889SApple OSS Distributions return self.hash_value.xGetScalarByName('smrh_count') 626*43a90889SApple OSS Distributions 627*43a90889SApple OSS Distributions @property 628*43a90889SApple OSS Distributions def rehashing(self): 629*43a90889SApple OSS Distributions return self.hash_value.xGetScalarByName('smrh_resizing') 630*43a90889SApple OSS Distributions 631*43a90889SApple OSS Distributions def iter(self, detailed=False): 632*43a90889SApple OSS Distributions obj_null = self.traits_value.chkGetChildMemberWithName('smrht_obj_type') 633*43a90889SApple OSS Distributions obj_ty = obj_null.GetType().GetArrayElementType().GetPointeeType() 634*43a90889SApple OSS Distributions lnk_offs = self.traits_value.xGetScalarByPath('.smrht.link_offset') 635*43a90889SApple OSS Distributions hash_arr = self.hash_value.xGetScalarByName('smrh_array') 636*43a90889SApple OSS Distributions hash_sz = 1 << (64 - ((hash_arr >> 48) & 0x00ff)) 637*43a90889SApple OSS Distributions hash_arr = obj_null.xCreateValueFromAddress(None, 638*43a90889SApple OSS Distributions hash_arr | 0xffff000000000000, gettype('struct smrq_slist_head')); 639*43a90889SApple OSS Distributions 640*43a90889SApple OSS Distributions if detailed: 641*43a90889SApple OSS Distributions return ( 642*43a90889SApple OSS Distributions (0, head_idx, e_idx, e.xCreateValueFromAddress(None, e.GetLoadAddress() - lnk_offs, obj_ty)) 643*43a90889SApple OSS Distributions for head_idx, head in enumerate(hash_arr.xIterSiblings(0, hash_sz)) 644*43a90889SApple OSS Distributions for e_idx, e in enumerate(iter_linked_list(head, '.next.__smr_ptr', '.first.__smr_ptr')) 645*43a90889SApple OSS Distributions ) 646*43a90889SApple OSS Distributions 647*43a90889SApple OSS Distributions return ( 648*43a90889SApple OSS Distributions e.xCreateValueFromAddress(None, e.GetLoadAddress() - lnk_offs, obj_ty) 649*43a90889SApple OSS Distributions for head in hash_arr.xIterSiblings(0, hash_sz) 650*43a90889SApple OSS Distributions for e in iter_linked_list(head, '.next.__smr_ptr', '.first.__smr_ptr') 651*43a90889SApple OSS Distributions ) 652*43a90889SApple OSS Distributions 653*43a90889SApple OSS Distributions 654*43a90889SApple OSS Distributionsclass SMRScalableHash(_Hash): 655*43a90889SApple OSS Distributions 656*43a90889SApple OSS Distributions def __init__(self, hash_value, traits_value): 657*43a90889SApple OSS Distributions """ 658*43a90889SApple OSS Distributions Create an smr hash table iterator 659*43a90889SApple OSS Distributions 660*43a90889SApple OSS Distributions @param hash_value (SBValue) 661*43a90889SApple OSS Distributions a reference to a struct smr_shash instance. 662*43a90889SApple OSS Distributions 663*43a90889SApple OSS Distributions @param traits_value (SBValue) 664*43a90889SApple OSS Distributions a reference to the traits for this hash table 665*43a90889SApple OSS Distributions """ 666*43a90889SApple OSS Distributions super().__init__() 667*43a90889SApple OSS Distributions self.hash_value = hash_value 668*43a90889SApple OSS Distributions self.traits_value = traits_value 669*43a90889SApple OSS Distributions 670*43a90889SApple OSS Distributions @property 671*43a90889SApple OSS Distributions def buckets(self): 672*43a90889SApple OSS Distributions shift = self.hash_value.xGetScalarByPath('.smrsh_state.curshift') 673*43a90889SApple OSS Distributions return (0xffffffff >> shift) + 1; 674*43a90889SApple OSS Distributions 675*43a90889SApple OSS Distributions @property 676*43a90889SApple OSS Distributions def count(self): 677*43a90889SApple OSS Distributions sbv = self.hash_value.chkGetChildMemberWithName('smrsh_count') 678*43a90889SApple OSS Distributions addr = sbv.GetValueAsAddress() 679*43a90889SApple OSS Distributions target = sbv.GetTarget() 680*43a90889SApple OSS Distributions ncpus = target.chkFindFirstGlobalVariable('zpercpu_early_count').xGetValueAsInteger() 681*43a90889SApple OSS Distributions pg_shift = target.chkFindFirstGlobalVariable('page_shift').xGetValueAsInteger() 682*43a90889SApple OSS Distributions 683*43a90889SApple OSS Distributions return sum( 684*43a90889SApple OSS Distributions target.xReadInt64(addr + (cpu << pg_shift)) 685*43a90889SApple OSS Distributions for cpu in range(ncpus) 686*43a90889SApple OSS Distributions ) 687*43a90889SApple OSS Distributions 688*43a90889SApple OSS Distributions @property 689*43a90889SApple OSS Distributions def rehashing(self): 690*43a90889SApple OSS Distributions curidx = self.hash_value.xGetScalarByPath('.smrsh_state.curidx'); 691*43a90889SApple OSS Distributions newidx = self.hash_value.xGetScalarByPath('.smrsh_state.newidx'); 692*43a90889SApple OSS Distributions return curidx != newidx 693*43a90889SApple OSS Distributions 694*43a90889SApple OSS Distributions def iter(self, detailed=False): 695*43a90889SApple OSS Distributions """ 696*43a90889SApple OSS Distributions @param detailed (bool) 697*43a90889SApple OSS Distributions whether to enumerate just elements, or show bucket info too 698*43a90889SApple OSS Distributions when bucket info is requested, enumeration returns a tuple of: 699*43a90889SApple OSS Distributions (table_index, bucket, index_in_bucket, element) 700*43a90889SApple OSS Distributions """ 701*43a90889SApple OSS Distributions 702*43a90889SApple OSS Distributions hash_value = self.hash_value 703*43a90889SApple OSS Distributions traits_value = self.traits_value 704*43a90889SApple OSS Distributions 705*43a90889SApple OSS Distributions obj_null = traits_value.chkGetChildMemberWithName('smrht_obj_type') 706*43a90889SApple OSS Distributions obj_ty = obj_null.GetType().GetArrayElementType().GetPointeeType() 707*43a90889SApple OSS Distributions lnk_offs = traits_value.xGetScalarByPath('.smrht.link_offset') 708*43a90889SApple OSS Distributions hashes = [] 709*43a90889SApple OSS Distributions 710*43a90889SApple OSS Distributions curidx = hash_value.xGetScalarByPath('.smrsh_state.curidx'); 711*43a90889SApple OSS Distributions newidx = hash_value.xGetScalarByPath('.smrsh_state.newidx'); 712*43a90889SApple OSS Distributions arrays = hash_value.chkGetChildMemberWithName('smrsh_array') 713*43a90889SApple OSS Distributions 714*43a90889SApple OSS Distributions array = arrays.chkGetChildAtIndex(curidx) 715*43a90889SApple OSS Distributions shift = hash_value.xGetScalarByPath('.smrsh_state.curshift') 716*43a90889SApple OSS Distributions hashes.append((curidx, array.Dereference(), shift)) 717*43a90889SApple OSS Distributions if newidx != curidx: 718*43a90889SApple OSS Distributions array = arrays.chkGetChildAtIndex(newidx) 719*43a90889SApple OSS Distributions shift = hash_value.xGetScalarByPath('.smrsh_state.newshift') 720*43a90889SApple OSS Distributions hashes.append((newidx, array.Dereference(), shift)) 721*43a90889SApple OSS Distributions 722*43a90889SApple OSS Distributions seen = set() 723*43a90889SApple OSS Distributions 724*43a90889SApple OSS Distributions def _iter_smr_shash_bucket(head): 725*43a90889SApple OSS Distributions addr = head.xGetScalarByName('lck_ptr_bits') 726*43a90889SApple OSS Distributions tg = head.GetTarget() 727*43a90889SApple OSS Distributions 728*43a90889SApple OSS Distributions while addr & 1 == 0: 729*43a90889SApple OSS Distributions addr &= 0xfffffffffffffffe 730*43a90889SApple OSS Distributions e = head.xCreateValueFromAddress(None, addr - lnk_offs, obj_ty) 731*43a90889SApple OSS Distributions if addr not in seen: 732*43a90889SApple OSS Distributions seen.add(addr) 733*43a90889SApple OSS Distributions yield e 734*43a90889SApple OSS Distributions addr = tg.xReadULong(addr); 735*43a90889SApple OSS Distributions 736*43a90889SApple OSS Distributions if detailed: 737*43a90889SApple OSS Distributions return ( 738*43a90889SApple OSS Distributions (hash_idx, head_idx, e_idx, e) 739*43a90889SApple OSS Distributions for hash_idx, hash_arr, hash_shift in hashes 740*43a90889SApple OSS Distributions for head_idx, head in enumerate(hash_arr.xIterSiblings( 741*43a90889SApple OSS Distributions 0, 1 + (0xffffffff >> hash_shift))) 742*43a90889SApple OSS Distributions for e_idx, e in enumerate(_iter_smr_shash_bucket(head)) 743*43a90889SApple OSS Distributions ) 744*43a90889SApple OSS Distributions 745*43a90889SApple OSS Distributions return ( 746*43a90889SApple OSS Distributions e 747*43a90889SApple OSS Distributions for hash_idx, hash_arr, hash_shift in hashes 748*43a90889SApple OSS Distributions for head in hash_arr.xIterSiblings( 749*43a90889SApple OSS Distributions 0, 1 + (0xffffffff >> hash_shift)) 750*43a90889SApple OSS Distributions for e in _iter_smr_shash_bucket(head) 751*43a90889SApple OSS Distributions ) 752*43a90889SApple OSS Distributions 753*43a90889SApple OSS Distributions 754*43a90889SApple OSS Distributions__all__ = [ 755*43a90889SApple OSS Distributions iter_linked_list.__name__, 756*43a90889SApple OSS Distributions iter_queue_entries.__name__, 757*43a90889SApple OSS Distributions iter_queue.__name__, 758*43a90889SApple OSS Distributions iter_circle_queue.__name__, 759*43a90889SApple OSS Distributions 760*43a90889SApple OSS Distributions iter_mpsc_queue.__name__, 761*43a90889SApple OSS Distributions 762*43a90889SApple OSS Distributions iter_priority_queue.__name__, 763*43a90889SApple OSS Distributions 764*43a90889SApple OSS Distributions iter_SLIST_HEAD.__name__, 765*43a90889SApple OSS Distributions iter_LIST_HEAD.__name__, 766*43a90889SApple OSS Distributions iter_STAILQ_HEAD.__name__, 767*43a90889SApple OSS Distributions iter_TAILQ_HEAD.__name__, 768*43a90889SApple OSS Distributions iter_SYS_QUEUE_HEAD.__name__, 769*43a90889SApple OSS Distributions iter_RB_HEAD.__name__, 770*43a90889SApple OSS Distributions RB_HEAD.__name__, 771*43a90889SApple OSS Distributions 772*43a90889SApple OSS Distributions iter_smr_queue.__name__, 773*43a90889SApple OSS Distributions SMRHash.__name__, 774*43a90889SApple OSS Distributions SMRScalableHash.__name__, 775*43a90889SApple OSS Distributions] 776