Changes in / [7f54356:b9376fe]


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/containers/list2.hfa

    r7f54356 rb9376fe  
    3939
    4040
    41 // The origin is the position encountered at the start of iteration,
    42 // signifying, "need to advance to the first element," and at the end
    43 // of iteration, signifying, "no more elements."  Normal comsumption of
    44 // an iterator runs ?`moveNext as the first step, and uses the return
    45 // of ?`moveNext as a guard, before dereferencing the iterator.  So
    46 // normal consumption of an iterator does not dereference an iterator
    47 // in origin position.  The value of a pointer (underlying a refence)
    48 // that is exposed publicly as an iteraor, and also a pointer stored
    49 // internally in a link field, is tagged, to indicate "is the origin"
    50 // (internally, is the list-head sentinel node), or untagged, to indicate
    51 // "is a regular node."  Intent is to help a user who dereferences an
    52 // iterator in origin position (which would be an API-use error on their
    53 // part), by failing fast.
    54 
    55 #if defined( __x86_64 )
    56     // Preferred case: tag in the most-significant bit.  Dereference
    57     // has been shown to segfault consistently.  Maintenance should
    58     // list more architectures as "ok" here, to let them use the
    59     // preferred case, when valid.
    60     #define ORIGIN_TAG_BITNO ( 8 * sizeof( size_t ) - 1 )
    61 #else
    62     // Fallback case: tag in the least-significant bit.  Dereference
    63     // will often give an alignment error, but may not, e.g. if
    64     // accessing a char-typed member.  32-bit x86 uses the most-
    65     // significant bit for real room on the heap.
    66     #define ORIGIN_TAG_BITNO 0
    67 #endif
     41
     42
     43#define ORIGIN_TAG_BITNO 63
    6844#define ORIGIN_TAG_MASK (((size_t)1) << ORIGIN_TAG_BITNO)
    6945
     
    7147#define ORIGIN_TAG_CLEAR(p) ((p) & ~ORIGIN_TAG_MASK)
    7248#define ORIGIN_TAG_QUERY(p) ((p) &  ORIGIN_TAG_MASK)
     49
     50// #define ORIGIN_TAG_SET(p)   (p)
     51// #define ORIGIN_TAG_CLEAR(p) (p)
     52// #define ORIGIN_TAG_QUERY(p) (0)
    7353
    7454
     
    130110        tE & list_pos_raw = list_pos;
    131111        tE & list_pos_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & list_pos_raw );
    132         asm( "" : : : "memory" );
    133112        tE & after_raw = * (list_pos_elem`inner`inner).next;
    134113        tE & after_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & after_raw );
     
    137116        (after_elem`inner`inner).prev = &to_insert;
    138117                (list_pos_elem`inner`inner).next = &to_insert;
    139         asm( "" : : : "memory" );
    140118        }
    141119
     
    148126        tE & list_pos_raw = list_pos;
    149127        tE & list_pos_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & list_pos_raw );
    150         asm( "" : : : "memory" );
    151128        tE & before_raw = * (list_pos_elem`inner`inner).prev;
    152129        tE & before_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & before_raw );
     
    155132        (before_elem`inner`inner).next = &to_insert;
    156133                (list_pos_elem`inner`inner).prev = &to_insert;
     134        }
     135
     136    static inline void doRemove(
     137        dlink(tE) & this_links, dlink(tE) & before_links, dlink(tE) & after_links,
     138        tE & before_target, tE & after_target ) {
     139
     140        before_links.next = &after_target;
     141        after_links.prev = &before_target;
     142
    157143        asm( "" : : : "memory" );
    158         }
    159 
     144
     145                this_links.prev = 0p;
     146                this_links.next = 0p;
     147    }
     148
     149        static inline tE & remove(diref(tE, tLinks) list_pos) {
     150                verify (&list_pos != 0p);
     151        tE & list_pos_elem = list_pos;
     152        verify( ! ORIGIN_TAG_QUERY((size_t) & list_pos_elem) );
     153        dlink(tE) & list_pos_links = list_pos_elem`inner`inner;
     154        tE & before_raw = * list_pos_links.prev;
     155        tE & before_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & before_raw );
     156        dlink(tE) & before_links = before_elem`inner`inner;
     157        tE & after_raw = * list_pos_links.next;
     158        tE & after_elem = * (tE *) ORIGIN_TAG_CLEAR( (size_t) & after_raw );
     159        dlink(tE) & after_links = after_elem`inner`inner;
     160
     161        doRemove(list_pos_links, before_links, after_links, before_raw, after_raw);
     162
     163        return list_pos_elem;
     164        }
     165/*   
    160166        static inline tE & remove(diref(tE, tLinks) list_pos) {
    161167                verify (&list_pos != 0p);
     
    171177        before_links.next = &after_raw;
    172178        after_links.prev = &before_raw;
    173         asm( "" : : : "memory" );
     179asm( "" : : : "memory" );
    174180                list_pos_links.prev = 0p;
    175181                list_pos_links.next = 0p;
    176         asm( "" : : : "memory" );
    177182        return list_pos_elem;
    178183        }
    179 
     184*/
    180185    static inline diref(tE, tLinks) ?`first( dlist(tE, tLinks) &lst ) {
    181186        tE * firstPtr = lst.next;
Note: See TracChangeset for help on using the changeset viewer.