Changeset c4c8571 for libcfa/src/concurrency/ready_subqueue.hfa
- Timestamp:
- Jul 28, 2022, 12:04:25 PM (2 years ago)
- Branches:
- ADT, ast-experimental, master, pthread-emulation
- Children:
- 32d1383, d0fcc82
- Parents:
- 3f95dab (diff), 2af1943 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/ready_subqueue.hfa
r3f95dab rc4c8571 6 6 7 7 // Intrusives lanes which are used by the relaxed ready queue 8 struct __attribute__((aligned(128))) __intrusive_lane_t { 9 struct thread$ * prev; 8 union __attribute__((aligned(64))) __intrusive_lane_t { 9 struct { 10 struct thread$ * prev; 10 11 11 // spin lock protecting the queue12 volatile bool lock;12 // spin lock protecting the queue 13 volatile bool lock; 13 14 14 __thread_desc_link anchor;15 __thread_desc_link anchor; 15 16 16 #if !defined(__CFA_NO_STATISTICS__) 17 unsigned cnt; 18 #endif 17 #if !defined(__CFA_NO_STATISTICS__) 18 unsigned cnt; 19 #endif 20 } l; 21 char __padding[192]; 19 22 }; 20 23 … … 22 25 static inline thread$ * mock_head(const __intrusive_lane_t & this) { 23 26 thread$ * rhead = (thread$ *)( 24 (uintptr_t)( &this. anchor ) - __builtin_offsetof( thread$, link )27 (uintptr_t)( &this.l.anchor ) - __builtin_offsetof( thread$, link ) 25 28 ); 26 29 return rhead; … … 30 33 // returns true of lane was empty before push, false otherwise 31 34 static inline void push( __intrusive_lane_t & this, thread$ * node ) { 32 /* paranoid */ verify( this.l ock );35 /* paranoid */ verify( this.l.lock ); 33 36 /* paranoid */ verify( node->link.next == 0p ); 34 37 /* paranoid */ verify( __atomic_load_n(&node->link.ts, __ATOMIC_RELAXED) == MAX ); 35 /* paranoid */ verify( this. prev->link.next == 0p );36 /* paranoid */ verify( __atomic_load_n(&this. prev->link.ts, __ATOMIC_RELAXED) == MAX );37 if( this. anchor.next == 0p ) {38 /* paranoid */ verify( this. anchor.next == 0p );39 /* paranoid */ verify( __atomic_load_n(&this. anchor.ts, __ATOMIC_RELAXED) == MAX );40 /* paranoid */ verify( __atomic_load_n(&this. anchor.ts, __ATOMIC_RELAXED) != 0 );41 /* paranoid */ verify( this. prev == mock_head( this ) );38 /* paranoid */ verify( this.l.prev->link.next == 0p ); 39 /* paranoid */ verify( __atomic_load_n(&this.l.prev->link.ts, __ATOMIC_RELAXED) == MAX ); 40 if( this.l.anchor.next == 0p ) { 41 /* paranoid */ verify( this.l.anchor.next == 0p ); 42 /* paranoid */ verify( __atomic_load_n(&this.l.anchor.ts, __ATOMIC_RELAXED) == MAX ); 43 /* paranoid */ verify( __atomic_load_n(&this.l.anchor.ts, __ATOMIC_RELAXED) != 0 ); 44 /* paranoid */ verify( this.l.prev == mock_head( this ) ); 42 45 } else { 43 /* paranoid */ verify( this. anchor.next != 0p );44 /* paranoid */ verify( __atomic_load_n(&this. anchor.ts, __ATOMIC_RELAXED) != MAX );45 /* paranoid */ verify( __atomic_load_n(&this. anchor.ts, __ATOMIC_RELAXED) != 0 );46 /* paranoid */ verify( this. prev != mock_head( this ) );46 /* paranoid */ verify( this.l.anchor.next != 0p ); 47 /* paranoid */ verify( __atomic_load_n(&this.l.anchor.ts, __ATOMIC_RELAXED) != MAX ); 48 /* paranoid */ verify( __atomic_load_n(&this.l.anchor.ts, __ATOMIC_RELAXED) != 0 ); 49 /* paranoid */ verify( this.l.prev != mock_head( this ) ); 47 50 } 48 51 49 52 // Get the relevant nodes locally 50 this. prev->link.next = node;51 __atomic_store_n(&this. prev->link.ts, rdtscl(), __ATOMIC_RELAXED);52 this. prev = node;53 this.l.prev->link.next = node; 54 __atomic_store_n(&this.l.prev->link.ts, rdtscl(), __ATOMIC_RELAXED); 55 this.l.prev = node; 53 56 #if !defined(__CFA_NO_STATISTICS__) 54 this. cnt++;57 this.l.cnt++; 55 58 #endif 56 59 } … … 60 63 // returns true of lane was empty before push, false otherwise 61 64 static inline [* thread$, unsigned long long] pop( __intrusive_lane_t & this ) { 62 /* paranoid */ verify( this.l ock );63 /* paranoid */ verify( this. anchor.next != 0p );64 /* paranoid */ verify( __atomic_load_n(&this. anchor.ts, __ATOMIC_RELAXED) != MAX );65 /* paranoid */ verify( __atomic_load_n(&this. anchor.ts, __ATOMIC_RELAXED) != 0 );65 /* paranoid */ verify( this.l.lock ); 66 /* paranoid */ verify( this.l.anchor.next != 0p ); 67 /* paranoid */ verify( __atomic_load_n(&this.l.anchor.ts, __ATOMIC_RELAXED) != MAX ); 68 /* paranoid */ verify( __atomic_load_n(&this.l.anchor.ts, __ATOMIC_RELAXED) != 0 ); 66 69 67 70 // Get the relevant nodes locally 68 thread$ * node = this. anchor.next;69 this. anchor.next = node->link.next;70 __atomic_store_n(&this. anchor.ts, __atomic_load_n(&node->link.ts, __ATOMIC_RELAXED), __ATOMIC_RELAXED);71 bool is_empty = this. anchor.next == 0p;71 thread$ * node = this.l.anchor.next; 72 this.l.anchor.next = node->link.next; 73 __atomic_store_n(&this.l.anchor.ts, __atomic_load_n(&node->link.ts, __ATOMIC_RELAXED), __ATOMIC_RELAXED); 74 bool is_empty = this.l.anchor.next == 0p; 72 75 node->link.next = 0p; 73 76 __atomic_store_n(&node->link.ts, ULLONG_MAX, __ATOMIC_RELAXED); 74 77 #if !defined(__CFA_NO_STATISTICS__) 75 this. cnt--;78 this.l.cnt--; 76 79 #endif 77 80 78 81 // Update head time stamp 79 if(is_empty) this. prev = mock_head( this );82 if(is_empty) this.l.prev = mock_head( this ); 80 83 81 unsigned long long ats = __atomic_load_n(&this. anchor.ts, __ATOMIC_RELAXED);84 unsigned long long ats = __atomic_load_n(&this.l.anchor.ts, __ATOMIC_RELAXED); 82 85 /* paranoid */ verify( node->link.next == 0p ); 83 86 /* paranoid */ verify( __atomic_load_n(&node->link.ts , __ATOMIC_RELAXED) == MAX ); … … 90 93 // Check whether or not list is empty 91 94 static inline bool is_empty(__intrusive_lane_t & this) { 92 return this. anchor.next == 0p;95 return this.l.anchor.next == 0p; 93 96 } 94 97 … … 96 99 static inline unsigned long long ts(__intrusive_lane_t & this) { 97 100 // Cannot verify 'emptiness' here since it may not be locked 98 /* paranoid */ verify(this. anchor.ts != 0);99 /* paranoid */ static_assert(__atomic_always_lock_free(sizeof(this. anchor.ts), &this.anchor.ts));100 return __atomic_load_n(&this. anchor.ts, __ATOMIC_RELAXED);101 /* paranoid */ verify(this.l.anchor.ts != 0); 102 /* paranoid */ static_assert(__atomic_always_lock_free(sizeof(this.l.anchor.ts), &this.l.anchor.ts)); 103 return __atomic_load_n(&this.l.anchor.ts, __ATOMIC_RELAXED); 101 104 }
Note: See TracChangeset
for help on using the changeset viewer.