Skip to content

Instantly share code, notes, and snippets.

@StephanDollberg
Last active January 16, 2023 22:34
Show Gist options
  • Save StephanDollberg/5587478f958d759a8c1d322a2617cc2a to your computer and use it in GitHub Desktop.
Save StephanDollberg/5587478f958d759a8c1d322a2617cc2a to your computer and use it in GitHub Desktop.
AtomicArrayUpdater bug
inf@jupiter:~/build/aeron$ clang++ --version
clang version 15.0.6 (Fedora 15.0.6-3.fc37)
Target: x86_64-redhat-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
O1
263136 0000000000519690 <aeron::concurrent::AtomicArrayUpdater<long>::load() const>:
263137 519690: 55 push rbp
263138 519691: 48 89 e5 mov rbp,rsp
263139 519694: 41 57 push r15
263140 519696: 41 56 push r14
263141 519698: 53 push rbx
263142 519699: 50 push rax
263143 51969a: 4c 8d 4f 08 lea r9,[rdi+0x8]
263144 51969e: 4c 8d 57 10 lea r10,[rdi+0x10]
263145 5196a2: 4c 8d 47 18 lea r8,[rdi+0x18]
263146 5196a6: 4d 89 cb mov r11,r9
263147 5196a9: 49 c1 eb 03 shr r11,0x3
263148 5196ad: 4d 89 d6 mov r14,r10
263149 5196b0: 49 c1 ee 03 shr r14,0x3
263150 5196b4: 4d 89 c7 mov r15,r8
263151 5196b7: 49 c1 ef 03 shr r15,0x3
263152 5196bb: 48 89 fb mov rbx,rdi
263153 5196be: 48 c1 eb 03 shr rbx,0x3
263154 5196c2: 66 66 66 66 66 2e 0f data16 data16 data16 data16 cs nop WORD PTR [rax+rax*1+0x0]
263155 5196c9: 1f 84 00 00 00 00 00
263156 5196d0: /-------> 41 80 bb 00 80 ff 7f cmp BYTE PTR [r11+0x7fff8000],0x0
263157 5196d7: | 00
263158 5196d8: /-----|-------- 75 49 jne 519723 <aeron::concurrent::AtomicArrayUpdater<long>::load() const+0x93>
263159 5196da: | | 49 8b 09 mov rcx,QWORD PTR [r9]
263160 5196dd: | | 41 80 be 00 80 ff 7f cmp BYTE PTR [r14+0x7fff8000],0x0
263161 5196e4: | | 00
263162 5196e5: | /--|-------- 75 44 jne 51972b <aeron::concurrent::AtomicArrayUpdater<long>::load() const+0x9b>
263163 5196e7: | | | 41 80 bf 00 80 ff 7f cmp BYTE PTR [r15+0x7fff8000],0x0
263164 5196ee: | | | 00
263165 5196ef: | | | /----- 75 25 jne 519716 <aeron::concurrent::AtomicArrayUpdater<long>::load() const+0x86>
263166 5196f1: | | | | 80 bb 00 80 ff 7f 00 cmp BYTE PTR [rbx+0x7fff8000],0x0
263167 5196f8: | | | | /-- 75 24 jne 51971e <aeron::concurrent::AtomicArrayUpdater<long>::load() const+0x8e>
263168 5196fa: | | | | | 48 8b 37 mov rsi,QWORD PTR [rdi]
263169 5196fd: | | | | | 48 39 f1 cmp rcx,rsi
263170 519700: | | | | | 49 0f 44 02 cmove rax,QWORD PTR [r10]
263171 519704: | | | | | 48 0f 44 57 18 cmove rdx,QWORD PTR [rdi+0x18]
263172 519709: | | \--|--|-- 75 c5 jne 5196d0 <aeron::concurrent::AtomicArrayUpdater<long>::load() const+0x40>
263173 51970b: | | | | 48 83 c4 08 add rsp,0x8
263174 51970f: | | | | 5b pop rbx
263175 519710: | | | | 41 5e pop r14
263176 519712: | | | | 41 5f pop r15
263177 519714: | | | | 5d pop rbp
263178 519715: | | | | c3 ret
263179 519716: | | \--|-> 4c 89 c7 mov rdi,r8
263180 519719: | | | e8 d2 1d fc ff call 4db4f0 <__asan_report_load8>
263181 51971e: | | \-> e8 cd 1d fc ff call 4db4f0 <__asan_report_load8>
263182 519723: \--|----------> 4c 89 cf mov rdi,r9
263183 519726: | e8 c5 1d fc ff call 4db4f0 <__asan_report_load8>
263184 51972b: \----------> 4c 89 d7 mov rdi,r10
263185 51972e: e8 bd 1d fc ff call 4db4f0 <__asan_report_load8>
263186 519733: 66 2e 0f 1f 84 00 00 cs nop WORD PTR [rax+rax*1+0x0]
263187 51973a: 00 00 00
263188 51973d: 0f 1f 00 nop DWORD PTR [rax]
263190 0000000000519740 <aeron::concurrent::AtomicArrayUpdater<long>::store(long*, unsigned long)>:
263191 519740: 55 push rbp
263192 519741: 48 89 e5 mov rbp,rsp
263193 519744: 48 89 f8 mov rax,rdi
263194 519747: 48 c1 e8 03 shr rax,0x3
263195 51974b: 80 b8 00 80 ff 7f 00 cmp BYTE PTR [rax+0x7fff8000],0x0
263196 519752: /-------------- 75 5b jne 5197af <aeron::concurrent::AtomicArrayUpdater<long>::store(long*, unsigned long)+0x6f>
263197 519754: | 48 8b 0f mov rcx,QWORD PTR [rdi]
263198 519757: | 80 b8 00 80 ff 7f 00 cmp BYTE PTR [rax+0x7fff8000],0x0
263199 51975e: | /----------- 75 54 jne 5197b4 <aeron::concurrent::AtomicArrayUpdater<long>::store(long*, unsigned long)+0x74>
263200 519760: | | 48 ff c1 inc rcx
263201 519763: | | 48 89 0f mov QWORD PTR [rdi],rcx
263202 519766: | | 4c 8d 47 10 lea r8,[rdi+0x10]
263203 51976a: | | 4c 89 c0 mov rax,r8
263204 51976d: | | 48 c1 e8 03 shr rax,0x3
263205 519771: | | 80 b8 00 80 ff 7f 00 cmp BYTE PTR [rax+0x7fff8000],0x0
263206 519778: | | /-------- 75 3f jne 5197b9 <aeron::concurrent::AtomicArrayUpdater<long>::store(long*, unsigned long)+0x79>
263207 51977a: | | | 48 89 77 10 mov QWORD PTR [rdi+0x10],rsi
263208 51977e: | | | 48 8d 47 18 lea rax,[rdi+0x18]
263209 519782: | | | 48 89 c6 mov rsi,rax
263210 519785: | | | 48 c1 ee 03 shr rsi,0x3
263211 519789: | | | 80 be 00 80 ff 7f 00 cmp BYTE PTR [rsi+0x7fff8000],0x0
263212 519790: | | | /----- 75 2f jne 5197c1 <aeron::concurrent::AtomicArrayUpdater<long>::store(long*, unsigned long)+0x81>
263213 519792: | | | | 48 89 57 18 mov QWORD PTR [rdi+0x18],rdx
263214 519796: | | | | 48 83 c7 08 add rdi,0x8
263215 51979a: | | | | 48 89 f8 mov rax,rdi
263216 51979d: | | | | 48 c1 e8 03 shr rax,0x3
263217 5197a1: | | | | 80 b8 00 80 ff 7f 00 cmp BYTE PTR [rax+0x7fff8000],0x0
263218 5197a8: | | | | /-- 75 1f jne 5197c9 <aeron::concurrent::AtomicArrayUpdater<long>::store(long*, unsigned long)+0x89>
263219 5197aa: | | | | | 48 89 0f mov QWORD PTR [rdi],rcx
263220 5197ad: | | | | | 5d pop rbp
263221 5197ae: | | | | | c3 ret
263222 5197af: \--|--|--|--|-> e8 3c 1d fc ff call 4db4f0 <__asan_report_load8>
263223 5197b4: \--|--|--|-> e8 97 20 fc ff call 4db850 <__asan_report_store8>
263224 5197b9: \--|--|-> 4c 89 c7 mov rdi,r8
263225 5197bc: | | e8 8f 20 fc ff call 4db850 <__asan_report_store8>
263226 5197c1: \--|-> 48 89 c7 mov rdi,rax
263227 5197c4: | e8 87 20 fc ff call 4db850 <__asan_report_store8>
263228 5197c9: \-> e8 82 20 fc ff call 4db850 <__asan_report_store8>
263229 5197ce: 66 90 xchg ax,ax
623 00000000004017e0 <aeron::concurrent::AtomicArrayUpdater<long>::load() const>:
624 4017e0: 55 push rbp
625 4017e1: 48 89 e5 mov rbp,rsp
626 4017e4: 66 66 66 2e 0f 1f 84 data16 data16 cs nop WORD PTR [rax+rax*1+0x0]
627 4017eb: 00 00 00 00 00
628 4017f0: /-> 48 8b 4f 08 mov rcx,QWORD PTR [rdi+0x8]
629 4017f4: | 4c 8b 4f 10 mov r9,QWORD PTR [rdi+0x10]
630 4017f8: | 4c 8b 47 18 mov r8,QWORD PTR [rdi+0x18]
631 4017fc: | 48 8b 37 mov rsi,QWORD PTR [rdi]
632 4017ff: | 48 39 f1 cmp rcx,rsi
633 401802: | 49 0f 44 c1 cmove rax,r9
634 401806: | 49 0f 44 d0 cmove rdx,r8
635 40180a: \-- 75 e4 jne 4017f0 <aeron::concurrent::AtomicArrayUpdater<long>::load() const+0x10>
636 40180c: 5d pop rbp
637 40180d: c3 ret
638 40180e: 66 90 xchg ax,ax
639
640 0000000000401810 <aeron::concurrent::AtomicArrayUpdater<long>::store(long*, unsigned long)>:
641 401810: 55 push rbp
642 401811: 48 89 e5 mov rbp,rsp
643 401814: 48 8b 07 mov rax,QWORD PTR [rdi]
644 401817: 48 ff c0 inc rax
645 40181a: 48 89 07 mov QWORD PTR [rdi],rax
646 40181d: 48 89 77 10 mov QWORD PTR [rdi+0x10],rsi
647 401821: 48 89 57 18 mov QWORD PTR [rdi+0x18],rdx
648 401825: 48 89 47 08 mov QWORD PTR [rdi+0x8],rax
649 401829: 5d pop rbp
650 40182a: c3 ret
651
O2
265101 000000000051b840 <aeron::concurrent::AtomicArrayUpdater<long>::load() const>:
265102 51b840: 55 push rbp
265103 51b841: 48 89 e5 mov rbp,rsp
265104 51b844: 41 57 push r15
265105 51b846: 41 56 push r14
265106 51b848: 53 push rbx
265107 51b849: 50 push rax
265108 51b84a: 4c 8d 4f 08 lea r9,[rdi+0x8]
265109 51b84e: 4c 8d 57 10 lea r10,[rdi+0x10]
265110 51b852: 4c 8d 47 18 lea r8,[rdi+0x18]
265111 51b856: 4d 89 cb mov r11,r9
265112 51b859: 49 c1 eb 03 shr r11,0x3
265113 51b85d: 4d 89 d6 mov r14,r10
265114 51b860: 49 c1 ee 03 shr r14,0x3
265115 51b864: 4d 89 c7 mov r15,r8
265116 51b867: 49 c1 ef 03 shr r15,0x3
265117 51b86b: 48 89 fb mov rbx,rdi
265118 51b86e: 48 c1 eb 03 shr rbx,0x3
265119 51b872: 66 66 66 66 66 2e 0f data16 data16 data16 data16 cs nop WORD PTR [rax+rax*1+0x0]
265120 51b879: 1f 84 00 00 00 00 00
265121 51b880: /-------> 41 80 bb 00 80 ff 7f cmp BYTE PTR [r11+0x7fff8000],0x0
265122 51b887: | 00
265123 51b888: /-----|-------- 75 47 jne 51b8d1 <aeron::concurrent::AtomicArrayUpdater<long>::load() const+0x91>
265124 51b88a: | | 49 8b 09 mov rcx,QWORD PTR [r9]
265125 51b88d: | | 41 80 be 00 80 ff 7f cmp BYTE PTR [r14+0x7fff8000],0x0
265126 51b894: | | 00
265127 51b895: | /--|-------- 75 42 jne 51b8d9 <aeron::concurrent::AtomicArrayUpdater<long>::load() const+0x99>
265128 51b897: | | | 41 80 bf 00 80 ff 7f cmp BYTE PTR [r15+0x7fff8000],0x0
265129 51b89e: | | | 00
265130 51b89f: | | | /----- 75 23 jne 51b8c4 <aeron::concurrent::AtomicArrayUpdater<long>::load() const+0x84>
265131 51b8a1: | | | | 80 bb 00 80 ff 7f 00 cmp BYTE PTR [rbx+0x7fff8000],0x0
265132 51b8a8: | | | | /-- 75 22 jne 51b8cc <aeron::concurrent::AtomicArrayUpdater<long>::load() const+0x8c>
265133 51b8aa: | | | | | 49 8b 02 mov rax,QWORD PTR [r10]
265134 51b8ad: | | | | | 48 8b 57 18 mov rdx,QWORD PTR [rdi+0x18]
265135 51b8b1: | | | | | 48 8b 37 mov rsi,QWORD PTR [rdi]
265136 51b8b4: | | | | | 48 39 f1 cmp rcx,rsi
265137 51b8b7: | | \--|--|-- 75 c7 jne 51b880 <aeron::concurrent::AtomicArrayUpdater<long>::load() const+0x40>
265138 51b8b9: | | | | 48 83 c4 08 add rsp,0x8
265139 51b8bd: | | | | 5b pop rbx
265140 51b8be: | | | | 41 5e pop r14
265141 51b8c0: | | | | 41 5f pop r15
265142 51b8c2: | | | | 5d pop rbp
265143 51b8c3: | | | | c3 ret
265144 51b8c4: | | \--|-> 4c 89 c7 mov rdi,r8
265145 51b8c7: | | | e8 24 fc fb ff call 4db4f0 <__asan_report_load8>
265146 51b8cc: | | \-> e8 1f fc fb ff call 4db4f0 <__asan_report_load8>
265147 51b8d1: \--|----------> 4c 89 cf mov rdi,r9
265148 51b8d4: | e8 17 fc fb ff call 4db4f0 <__asan_report_load8>
265149 51b8d9: \----------> 4c 89 d7 mov rdi,r10
265150 51b8dc: e8 0f fc fb ff call 4db4f0 <__asan_report_load8>
265151 51b8e1: 66 2e 0f 1f 84 00 00 cs nop WORD PTR [rax+rax*1+0x0]
265152 51b8e8: 00 00 00
265153 51b8eb: 0f 1f 44 00 00 nop DWORD PTR [rax+rax*1+0x0]
265155 000000000051b8f0 <aeron::concurrent::AtomicArrayUpdater<long>::store(long*, unsigned long)>:
265156 51b8f0: 55 push rbp
265157 51b8f1: 48 89 e5 mov rbp,rsp
265158 51b8f4: 48 89 f8 mov rax,rdi
265159 51b8f7: 48 c1 e8 03 shr rax,0x3
265160 51b8fb: 80 b8 00 80 ff 7f 00 cmp BYTE PTR [rax+0x7fff8000],0x0
265161 51b902: /-------------- 75 5b jne 51b95f <aeron::concurrent::AtomicArrayUpdater<long>::store(long*, unsigned long)+0x6f>
265162 51b904: | 48 8b 0f mov rcx,QWORD PTR [rdi]
265163 51b907: | 80 b8 00 80 ff 7f 00 cmp BYTE PTR [rax+0x7fff8000],0x0
265164 51b90e: | /----------- 75 54 jne 51b964 <aeron::concurrent::AtomicArrayUpdater<long>::store(long*, unsigned long)+0x74>
265165 51b910: | | 48 ff c1 inc rcx
265166 51b913: | | 48 89 0f mov QWORD PTR [rdi],rcx
265167 51b916: | | 4c 8d 47 10 lea r8,[rdi+0x10]
265168 51b91a: | | 4c 89 c0 mov rax,r8
265169 51b91d: | | 48 c1 e8 03 shr rax,0x3
265170 51b921: | | 80 b8 00 80 ff 7f 00 cmp BYTE PTR [rax+0x7fff8000],0x0
265171 51b928: | | /-------- 75 3f jne 51b969 <aeron::concurrent::AtomicArrayUpdater<long>::store(long*, unsigned long)+0x79>
265172 51b92a: | | | 48 89 77 10 mov QWORD PTR [rdi+0x10],rsi
265173 51b92e: | | | 48 8d 47 18 lea rax,[rdi+0x18]
265174 51b932: | | | 48 89 c6 mov rsi,rax
265175 51b935: | | | 48 c1 ee 03 shr rsi,0x3
265176 51b939: | | | 80 be 00 80 ff 7f 00 cmp BYTE PTR [rsi+0x7fff8000],0x0
265177 51b940: | | | /----- 75 2f jne 51b971 <aeron::concurrent::AtomicArrayUpdater<long>::store(long*, unsigned long)+0x81>
265178 51b942: | | | | 48 89 57 18 mov QWORD PTR [rdi+0x18],rdx
265179 51b946: | | | | 48 83 c7 08 add rdi,0x8
265180 51b94a: | | | | 48 89 f8 mov rax,rdi
265181 51b94d: | | | | 48 c1 e8 03 shr rax,0x3
265182 51b951: | | | | 80 b8 00 80 ff 7f 00 cmp BYTE PTR [rax+0x7fff8000],0x0
265183 51b958: | | | | /-- 75 1f jne 51b979 <aeron::concurrent::AtomicArrayUpdater<long>::store(long*, unsigned long)+0x89>
265184 51b95a: | | | | | 48 89 0f mov QWORD PTR [rdi],rcx
265185 51b95d: | | | | | 5d pop rbp
265186 51b95e: | | | | | c3 ret
265187 51b95f: \--|--|--|--|-> e8 8c fb fb ff call 4db4f0 <__asan_report_load8>
265188 51b964: \--|--|--|-> e8 e7 fe fb ff call 4db850 <__asan_report_store8>
265189 51b969: \--|--|-> 4c 89 c7 mov rdi,r8
265190 51b96c: | | e8 df fe fb ff call 4db850 <__asan_report_store8>
265191 51b971: \--|-> 48 89 c7 mov rdi,rax
265192 51b974: | e8 d7 fe fb ff call 4db850 <__asan_report_store8>
265193 51b979: \-> e8 d2 fe fb ff call 4db850 <__asan_report_store8>
265194 51b97e: 66 90 xchg ax,ax
O2 no asan
645 0000000000401820 <aeron::concurrent::AtomicArrayUpdater<long>::load() const>:
646 401820: 55 push rbp
647 401821: 48 89 e5 mov rbp,rsp
648 401824: 66 66 66 2e 0f 1f 84 data16 data16 cs nop WORD PTR [rax+rax*1+0x0]
649 40182b: 00 00 00 00 00
650 401830: /-> 48 8b 4f 08 mov rcx,QWORD PTR [rdi+0x8]
651 401834: | 48 8b 47 10 mov rax,QWORD PTR [rdi+0x10]
652 401838: | 48 8b 57 18 mov rdx,QWORD PTR [rdi+0x18]
653 40183c: | 48 8b 37 mov rsi,QWORD PTR [rdi]
654 40183f: | 48 39 f1 cmp rcx,rsi
655 401842: \-- 75 ec jne 401830 <aeron::concurrent::AtomicArrayUpdater<long>::load() const+0x10>
656 401844: 5d pop rbp
657 401845: c3 ret
658 401846: 66 2e 0f 1f 84 00 00 cs nop WORD PTR [rax+rax*1+0x0]
659 40184d: 00 00 00
660
661 0000000000401850 <aeron::concurrent::AtomicArrayUpdater<long>::store(long*, unsigned long)>:
662 401850: 55 push rbp
663 401851: 48 89 e5 mov rbp,rsp
664 401854: 48 8b 07 mov rax,QWORD PTR [rdi]
665 401857: 48 ff c0 inc rax
666 40185a: 48 89 07 mov QWORD PTR [rdi],rax
667 40185d: 48 89 77 10 mov QWORD PTR [rdi+0x10],rsi
668 401861: 48 89 57 18 mov QWORD PTR [rdi+0x18],rdx
669 401865: 48 89 47 08 mov QWORD PTR [rdi+0x8],rax
670 401869: 5d pop rbp
671 40186a: c3 ret
O2 gcc
532 00000000004016c0 <aeron::concurrent::AtomicArrayUpdater<long>::load() const>:
533 4016c0: 4c 8d 47 08 lea r8,[rdi+0x8]
534 4016c4: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
535 4016c8: /-> 49 8b 00 mov rax,QWORD PTR [r8]
536 4016cb: | 48 8b 77 10 mov rsi,QWORD PTR [rdi+0x10]
537 4016cf: | 48 8b 4f 18 mov rcx,QWORD PTR [rdi+0x18]
538 4016d3: | 48 8b 17 mov rdx,QWORD PTR [rdi]
539 4016d6: | 48 39 c2 cmp rdx,rax
540 4016d9: \-- 75 ed jne 4016c8 <aeron::concurrent::AtomicArrayUpdater<long>::load() const+0x8>
541 4016db: 48 89 f0 mov rax,rsi
542 4016de: 48 89 ca mov rdx,rcx
543 4016e1: c3 ret
544 4016e2: 66 2e 0f 1f 84 00 00 cs nop WORD PTR [rax+rax*1+0x0]
545 4016e9: 00 00 00
546 4016ec: 0f 1f 40 00 nop DWORD PTR [rax+0x0]
547
548 00000000004016f0 <aeron::concurrent::AtomicArrayUpdater<long>::store(long*, unsigned long)>:
549 4016f0: 48 8b 07 mov rax,QWORD PTR [rdi]
550 4016f3: 48 83 c0 01 add rax,0x1
551 4016f7: 48 89 07 mov QWORD PTR [rdi],rax
552 4016fa: 48 89 77 10 mov QWORD PTR [rdi+0x10],rsi
553 4016fe: 48 89 57 18 mov QWORD PTR [rdi+0x18],rdx
554 401702: 48 89 47 08 mov QWORD PTR [rdi+0x8],rax
555 401706: c3 ret
556 401707: 66 0f 1f 84 00 00 00 nop WORD PTR [rax+rax*1+0x0]
557 40170e: 00 00
#include <cstddef>
#include <utility>
#include <atomic>
#include <thread>
#include <iostream>
namespace aeron
{
namespace util
{
template<typename E>
std::pair<E *, std::size_t> addToArray(E *oldArray, std::size_t oldLength, E element)
{
std::size_t newLength = oldLength + 1;
E *newArray = new E[newLength];
// std::printf("push %p %lu\n", newArray, newLength);
for (std::size_t i = 0; i < oldLength; i++)
{
newArray[i] = oldArray[i];
}
newArray[oldLength] = element;
return { newArray, newLength };
}
template<typename E>
std::pair<E *, std::size_t> removeFromArray(E *oldArray, std::size_t oldLength, std::size_t index)
{
std::size_t newLength = oldLength - 1;
E *newArray = new E[newLength];
// std::printf("push %p %lu\n", newArray, newLength);
for (std::size_t i = 0, j = 0; i < oldLength; i++)
{
if (i != index)
{
newArray[j++] = oldArray[i];
}
}
return { newArray, newLength };
}
}
namespace concurrent
{
template<typename E>
class AtomicArrayUpdater
{
public:
AtomicArrayUpdater() = default;
~AtomicArrayUpdater() = default;
__attribute__((noinline))
inline std::pair<E *, std::size_t> load() const
{
while (true)
{
std::int64_t changeNumber = m_endChange.load(std::memory_order_acquire);
E *array = m_array.first;
std::size_t length = m_array.second;
std::atomic_thread_fence(std::memory_order_acquire);
if (changeNumber == m_beginChange.load(std::memory_order_acquire))
{
return { array, length };
}
}
}
__attribute__((noinline))
inline void store(E *array, std::size_t length)
{
std::int64_t changeNumber = m_beginChange.load(std::memory_order_relaxed) + 1;
m_beginChange.store(changeNumber, std::memory_order_release);
std::atomic_thread_fence(std::memory_order_release);
m_array.first = array;
m_array.second = length;
m_endChange.store(changeNumber, std::memory_order_release);
}
std::pair<E *, std::size_t> addElement(E element)
{
std::pair<E *, std::size_t> oldArray = load();
std::pair<E *, std::size_t> newArray = aeron::util::addToArray(oldArray.first, oldArray.second, element);
store(newArray.first, newArray.second);
return oldArray;
}
template<typename F>
std::pair<E *, std::size_t> removeElement(F &&func)
{
std::pair<E *, std::size_t> oldArray = load();
for (std::size_t i = 0, length = oldArray.second; i < length; i++)
{
if (func(oldArray.first[i]))
{
std::pair<E *, std::size_t> newArray = aeron::util::removeFromArray(oldArray.first, length, i);
store(newArray.first, newArray.second);
return { oldArray.first, i };
}
}
return { nullptr, 0 };
}
private:
std::atomic<std::int64_t> m_beginChange = { -1 };
std::atomic<std::int64_t> m_endChange = { -1 };
std::pair<E*, std::size_t> m_array = { nullptr, 0 };
};
}}
int main() {
std::int64_t counter = 0;
aeron::concurrent::AtomicArrayUpdater<std::int64_t> aau;
aau.addElement(1);
aau.addElement(2);
aau.addElement(3);
aau.addElement(4);
aau.addElement(5);
const std::int64_t max = 100000000;
std::thread writer([&] () {
std::int64_t i = 1;
while (i < max) {
++i;
auto res = aau.removeElement([&] (auto ele) {
return ele == i;
});
aau.addElement(i + 5);
}
});
std::thread reader([&] () {
std::int64_t i = 0;
while (i < max * 100)
{
++i;
auto res = aau.load();
if (res.first == nullptr)
{
continue;
}
// std::printf("pop %p %lu\n", res.first, res.second);
counter += res.first[res.second - 1];
}
});
writer.join();
reader.join();
std::cout << counter << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment