build/app/test/3062f5d@@dpdk-test@exe/test_seqlock.c.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 : #define INTERRUPTED_READER_FREQUENCY 1000 #define READER_INTERRUPT_TIME 1000 /* us */ static int reader_run(void *arg) { 0: 41 57 push %r15 2: 48 8d 47 08 lea 0x8(%rdi),%rax 6: 41 56 push %r14 8: 49 89 fe mov %rdi,%r14 b: 41 55 push %r13 d: 41 54 push %r12 struct reader *r = arg; int rc = TEST_SUCCESS; f: 45 31 e4 xor %r12d,%r12d { 12: 55 push %rbp 13: 53 push %rbx 14: 48 83 ec 18 sub $0x18,%rsp 18: 48 89 44 24 08 mov %rax,0x8(%rsp) 1d: 0f 1f 00 nopl (%rax) while (__atomic_load_n(&r->stop, __ATOMIC_RELAXED) == 0 && 20: 48 8b 44 24 08 mov 0x8(%rsp),%rax 25: 0f b6 00 movzbl (%rax),%eax 28: 84 c0 test %al,%al 2a: 75 7f jne ab 2c: 45 85 e4 test %r12d,%r12d 2f: 0f 85 88 00 00 00 jne bd uint32_t sn; uint64_t a; uint64_t b; uint64_t c; interrupted = rte_rand_max(INTERRUPTED_READER_FREQUENCY) == 0; 35: bf e8 03 00 00 mov $0x3e8,%edi struct data *data = r->data; 3a: 49 8b 1e mov (%r14),%rbx interrupted = rte_rand_max(INTERRUPTED_READER_FREQUENCY) == 0; 3d: e8 00 00 00 00 callq 42 42: 49 89 c7 mov %rax,%r15 45: eb 22 jmp 69 47: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1) 4e: 00 00 /* An odd sequence number means the protected data was being * modified already at the point of the rte_seqcount_read_begin() * call. */ if (unlikely(begin_sn & 1)) 50: 40 f6 c5 01 test $0x1,%bpl sn = rte_seqlock_read_begin(&data->lock); a = data->a; if (interrupted) rte_delay_us_block(READER_INTERRUPT_TIME); c = data->c; 54: 48 8b 8b 80 00 00 00 mov 0x80(%rbx),%rcx b = data->b; 5b: 48 8b 53 40 mov 0x40(%rbx),%rdx 5f: 75 08 jne 69 return true; /* make sure the data loads happens before the sn load */ rte_atomic_thread_fence(__ATOMIC_ACQUIRE); end_sn = __atomic_load_n(&seqcount->sn, __ATOMIC_RELAXED); 61: 44 8b 03 mov (%rbx),%r8d } while (rte_seqlock_read_retry(&data->lock, sn)); 64: 44 39 c5 cmp %r8d,%ebp 67: 74 17 je 80 if (interrupted) 69: 4d 85 ff test %r15,%r15 return __atomic_load_n(&seqcount->sn, __ATOMIC_ACQUIRE); 6c: 8b 2b mov (%rbx),%ebp a = data->a; 6e: 4c 8b 6b 08 mov 0x8(%rbx),%r13 if (interrupted) 72: 75 dc jne 50 rte_delay_us_block(READER_INTERRUPT_TIME); 74: bf e8 03 00 00 mov $0x3e8,%edi 79: e8 00 00 00 00 callq 7e 7e: eb d0 jmp 50 if (a != b || b != c) { 80: 48 39 d1 cmp %rdx,%rcx 83: 75 05 jne 8a 85: 49 39 d5 cmp %rdx,%r13 88: 74 96 je 20 printf("Reader observed inconsistent data values " 8a: 31 c0 xor %eax,%eax 8c: 4c 89 ee mov %r13,%rsi 8f: bf 00 00 00 00 mov $0x0,%edi 94: e8 00 00 00 00 callq 99 while (__atomic_load_n(&r->stop, __ATOMIC_RELAXED) == 0 && 99: 48 8b 44 24 08 mov 0x8(%rsp),%rax "%" PRIu64 " %" PRIu64 " %" PRIu64 "\n", a, b, c); rc = TEST_FAILED; 9e: 41 bc ff ff ff ff mov $0xffffffff,%r12d while (__atomic_load_n(&r->stop, __ATOMIC_RELAXED) == 0 && a4: 0f b6 00 movzbl (%rax),%eax a7: 84 c0 test %al,%al a9: 74 81 je 2c } } return rc; } ab: 48 83 c4 18 add $0x18,%rsp af: 44 89 e0 mov %r12d,%eax b2: 5b pop %rbx b3: 5d pop %rbp b4: 41 5c pop %r12 b6: 41 5d pop %r13 b8: 41 5e pop %r14 ba: 41 5f pop %r15 bc: c3 retq bd: 41 bc ff ff ff ff mov $0xffffffff,%r12d c3: eb e6 jmp ab c5: 90 nop c6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) cd: 00 00 00 00000000000000d0 : { d0: 41 55 push %r13 d2: 41 54 push %r12 d4: 55 push %rbp d5: 53 push %rbx d6: 48 89 fb mov %rdi,%rbx d9: 48 83 ec 08 sub $0x8,%rsp "c"(0x10000)); return tsc.tsc_64; } #endif asm volatile("rdtsc" : dd: 0f 31 rdtsc df: 48 c1 e2 20 shl $0x20,%rdx e3: 89 c5 mov %eax,%ebp e5: 48 09 d5 or %rdx,%rbp { #ifdef RTE_LIBEAL_USE_HPET switch(eal_timer_source) { case EAL_TIMER_TSC: #endif return rte_get_tsc_hz(); e8: e8 00 00 00 00 callq ed WRITER_RUNTIME * rte_get_timer_hz(); ed: 48 85 c0 test %rax,%rax f0: 0f 88 0a 01 00 00 js 200 deadline = rte_get_timer_cycles() + f6: 48 85 ed test %rbp,%rbp WRITER_RUNTIME * rte_get_timer_hz(); f9: c4 e1 f3 2a c8 vcvtsi2sd %rax,%xmm1,%xmm1 deadline = rte_get_timer_cycles() + fe: 0f 88 1a 01 00 00 js 21e 104: c4 e1 fb 2a c5 vcvtsi2sd %rbp,%xmm0,%xmm0 109: c4 e2 f1 b9 05 00 00 vfmadd231sd 0x0(%rip),%xmm1,%xmm0 # 112 110: 00 00 112: c5 fb 10 0d 00 00 00 vmovsd 0x0(%rip),%xmm1 # 11a 119: 00 11a: c5 f9 2e c1 vucomisd %xmm1,%xmm0 11e: 0f 83 bc 00 00 00 jae 1e0 124: c4 61 fb 2c e8 vcvttsd2si %xmm0,%r13 129: 0f 31 rdtsc 12b: 48 c1 e2 20 shl $0x20,%rdx 12f: 89 c0 mov %eax,%eax 131: 4c 8d 63 04 lea 0x4(%rbx),%r12 135: 48 09 d0 or %rdx,%rax while (rte_get_timer_cycles() < deadline) { 138: 49 39 c5 cmp %rax,%r13 13b: 77 3d ja 17a 13d: e9 8e 00 00 00 jmpq 1d0 142: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) static inline void rte_seqcount_write_end(rte_seqcount_t *seqcount) { uint32_t sn; sn = seqcount->sn + 1; 148: 8b 03 mov (%rbx),%eax data->a = new_value; 14a: 48 89 6b 08 mov %rbp,0x8(%rbx) 14e: 83 c0 01 add $0x1,%eax /* Synchronizes-with the load acquire in rte_seqcount_read_begin(). */ __atomic_store_n(&seqcount->sn, sn, __ATOMIC_RELEASE); 151: 89 03 mov %eax,(%rbx) static inline void rte_spinlock_unlock (rte_spinlock_t *sl) { int unlock_val = 0; asm volatile ( 153: 31 c0 xor %eax,%eax 155: 41 87 04 24 xchg %eax,(%r12) delay = rte_rand_max(WRITER_MAX_DELAY); 159: bf 64 00 00 00 mov $0x64,%edi 15e: e8 00 00 00 00 callq 163 rte_delay_us_block(delay); 163: 89 c7 mov %eax,%edi 165: e8 00 00 00 00 callq 16a 16a: 0f 31 rdtsc 16c: 48 c1 e2 20 shl $0x20,%rdx 170: 89 c0 mov %eax,%eax 172: 48 09 d0 or %rdx,%rax while (rte_get_timer_cycles() < deadline) { 175: 49 39 c5 cmp %rax,%r13 178: 76 56 jbe 1d0 new_value = rte_rand(); 17a: e8 00 00 00 00 callq 17f interrupted = rte_rand_max(INTERRUPTED_WRITER_FREQUENCY) == 0; 17f: bf e8 03 00 00 mov $0x3e8,%edi new_value = rte_rand(); 184: 48 89 c5 mov %rax,%rbp interrupted = rte_rand_max(INTERRUPTED_WRITER_FREQUENCY) == 0; 187: e8 00 00 00 00 callq 18c asm volatile ( 18c: ba 01 00 00 00 mov $0x1,%edx 191: 41 87 14 24 xchg %edx,(%r12) 195: 85 d2 test %edx,%edx 197: 74 0b je 1a4 199: f3 90 pause 19b: 41 83 3c 24 00 cmpl $0x0,(%r12) 1a0: 75 f7 jne 199 1a2: eb ed jmp 191 sn = seqcount->sn + 1; 1a4: 8b 0b mov (%rbx),%ecx if (interrupted) 1a6: 48 85 c0 test %rax,%rax 1a9: 8d 51 01 lea 0x1(%rcx),%edx __atomic_store_n(&seqcount->sn, sn, __ATOMIC_RELAXED); 1ac: 89 13 mov %edx,(%rbx) data->c = new_value; 1ae: 48 89 ab 80 00 00 00 mov %rbp,0x80(%rbx) data->b = new_value; 1b5: 48 89 6b 40 mov %rbp,0x40(%rbx) if (interrupted) 1b9: 75 8d jne 148 rte_delay_us_block(WRITER_INTERRUPT_TIME); 1bb: bf 01 00 00 00 mov $0x1,%edi 1c0: e8 00 00 00 00 callq 1c5 1c5: eb 81 jmp 148 1c7: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1) 1ce: 00 00 } 1d0: 48 83 c4 08 add $0x8,%rsp 1d4: 31 c0 xor %eax,%eax 1d6: 5b pop %rbx 1d7: 5d pop %rbp 1d8: 41 5c pop %r12 1da: 41 5d pop %r13 1dc: c3 retq 1dd: 0f 1f 00 nopl (%rax) deadline = rte_get_timer_cycles() + 1e0: c5 fb 5c c1 vsubsd %xmm1,%xmm0,%xmm0 1e4: 48 b8 00 00 00 00 00 movabs $0x8000000000000000,%rax 1eb: 00 00 80 1ee: c4 61 fb 2c e8 vcvttsd2si %xmm0,%r13 1f3: 49 31 c5 xor %rax,%r13 1f6: e9 2e ff ff ff jmpq 129 1fb: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) WRITER_RUNTIME * rte_get_timer_hz(); 200: 48 89 c2 mov %rax,%rdx 203: 83 e0 01 and $0x1,%eax 206: 48 d1 ea shr %rdx 209: 48 09 c2 or %rax,%rdx deadline = rte_get_timer_cycles() + 20c: 48 85 ed test %rbp,%rbp WRITER_RUNTIME * rte_get_timer_hz(); 20f: c4 e1 f3 2a ca vcvtsi2sd %rdx,%xmm1,%xmm1 214: c5 f3 58 c9 vaddsd %xmm1,%xmm1,%xmm1 deadline = rte_get_timer_cycles() + 218: 0f 89 e6 fe ff ff jns 104 21e: 48 89 e8 mov %rbp,%rax 221: 83 e5 01 and $0x1,%ebp 224: 48 d1 e8 shr %rax 227: 48 09 e8 or %rbp,%rax 22a: c4 e1 fb 2a c0 vcvtsi2sd %rax,%xmm0,%xmm0 22f: c5 fb 58 c0 vaddsd %xmm0,%xmm0,%xmm0 233: e9 d1 fe ff ff jmpq 109 238: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1) 23f: 00 0000000000000240 : /* Only a compile-time test */ static rte_seqlock_t __rte_unused static_init_lock = RTE_SEQLOCK_INITIALIZER; static int test_seqlock(void) { 240: 41 57 push %r15 242: 41 56 push %r14 244: 41 55 push %r13 246: 41 54 push %r12 248: 55 push %rbp 249: 53 push %rbx 24a: 48 81 ec 18 0a 00 00 sub $0xa18,%rsp unsigned int lcore_id; unsigned int reader_lcore_ids[RTE_MAX_LCORE]; unsigned int worker_writer_lcore_id = 0; int rc = TEST_SUCCESS; num_lcores = rte_lcore_count(); 251: e8 00 00 00 00 callq 256 if (num_lcores < MIN_LCORE_COUNT) { 256: 83 f8 03 cmp $0x3,%eax num_lcores = rte_lcore_count(); 259: 41 89 c6 mov %eax,%r14d if (num_lcores < MIN_LCORE_COUNT) { 25c: 77 22 ja 280 printf("Too few cores to run test. Skipping.\n"); 25e: bf 00 00 00 00 mov $0x0,%edi 263: e8 00 00 00 00 callq 268 return TEST_SKIPPED; 268: b8 4d 00 00 00 mov $0x4d,%eax } rte_free(data); return rc; } 26d: 48 81 c4 18 0a 00 00 add $0xa18,%rsp 274: 5b pop %rbx 275: 5d pop %rbp 276: 41 5c pop %r12 278: 41 5d pop %r13 27a: 41 5e pop %r14 27c: 41 5f pop %r15 27e: c3 retq 27f: 90 nop data = rte_zmalloc(NULL, sizeof(struct data), 0); 280: 31 d2 xor %edx,%edx 282: 31 ff xor %edi,%edi 284: be c0 00 00 00 mov $0xc0,%esi 289: e8 00 00 00 00 callq 28e if (data == NULL) { 28e: 48 85 c0 test %rax,%rax data = rte_zmalloc(NULL, sizeof(struct data), 0); 291: 49 89 c7 mov %rax,%r15 if (data == NULL) { 294: 0f 84 1b 01 00 00 je 3b5 RTE_LCORE_FOREACH_WORKER(lcore_id) { 29a: 31 d2 xor %edx,%edx 29c: be 01 00 00 00 mov $0x1,%esi 2a1: bf ff ff ff ff mov $0xffffffff,%edi 2a6: e8 00 00 00 00 callq 2ab 2ab: 83 f8 7f cmp $0x7f,%eax 2ae: 89 c3 mov %eax,%ebx unsigned int worker_writer_lcore_id = 0; 2b0: c7 44 24 0c 00 00 00 movl $0x0,0xc(%rsp) 2b7: 00 RTE_LCORE_FOREACH_WORKER(lcore_id) { 2b8: 77 6f ja 329 i = 0; 2ba: 45 31 e4 xor %r12d,%r12d 2bd: 4c 8d ac 24 10 02 00 lea 0x210(%rsp),%r13 2c4: 00 2c5: eb 35 jmp 2fc 2c7: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1) 2ce: 00 00 rte_eal_remote_launch(writer_run, data, lcore_id); 2d0: 89 da mov %ebx,%edx 2d2: 4c 89 fe mov %r15,%rsi 2d5: bf 00 00 00 00 mov $0x0,%edi 2da: e8 00 00 00 00 callq 2df 2df: 89 5c 24 0c mov %ebx,0xc(%rsp) RTE_LCORE_FOREACH_WORKER(lcore_id) { 2e3: 31 d2 xor %edx,%edx 2e5: 89 df mov %ebx,%edi 2e7: be 01 00 00 00 mov $0x1,%esi 2ec: e8 00 00 00 00 callq 2f1 i++; 2f1: 41 83 c4 01 add $0x1,%r12d RTE_LCORE_FOREACH_WORKER(lcore_id) { 2f5: 83 f8 7f cmp $0x7f,%eax 2f8: 89 c3 mov %eax,%ebx 2fa: 77 3c ja 338 if (i == 0) { 2fc: 45 85 e4 test %r12d,%r12d 2ff: 74 cf je 2d0 struct reader *reader = &readers[reader_idx]; 301: 41 8d 6c 24 ff lea -0x1(%r12),%ebp rte_eal_remote_launch(reader_run, reader, lcore_id); 306: 89 da mov %ebx,%edx 308: bf 00 00 00 00 mov $0x0,%edi struct reader *reader = &readers[reader_idx]; 30d: 48 89 ee mov %rbp,%rsi 310: 48 c1 e6 04 shl $0x4,%rsi 314: 4c 01 ee add %r13,%rsi reader->data = data; 317: 4c 89 3e mov %r15,(%rsi) reader->stop = 0; 31a: c6 46 08 00 movb $0x0,0x8(%rsi) rte_eal_remote_launch(reader_run, reader, lcore_id); 31e: e8 00 00 00 00 callq 323 reader_lcore_ids[reader_idx] = lcore_id; 323: 89 5c ac 10 mov %ebx,0x10(%rsp,%rbp,4) 327: eb ba jmp 2e3 329: 4c 8d ac 24 10 02 00 lea 0x210(%rsp),%r13 330: 00 331: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) if (writer_run(data) != 0 || 338: 4c 89 ff mov %r15,%rdi rc = TEST_FAILED; 33b: 41 bc ff ff ff ff mov $0xffffffff,%r12d if (writer_run(data) != 0 || 341: e8 8a fd ff ff callq d0 346: 85 c0 test %eax,%eax 348: 74 54 je 39e 34a: 41 8d 46 fd lea -0x3(%r14),%eax 34e: 48 8d 6c 24 10 lea 0x10(%rsp),%rbp 353: 49 8d 5d 08 lea 0x8(%r13),%rbx 357: 48 c1 e0 04 shl $0x4,%rax 35b: 4d 8d 74 05 18 lea 0x18(%r13,%rax,1),%r14 rc = TEST_FAILED; 360: 41 bd ff ff ff ff mov $0xffffffff,%r13d 366: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 36d: 00 00 00 __atomic_store_n(&reader->stop, 1, __ATOMIC_RELAXED); 370: c6 03 01 movb $0x1,(%rbx) if (rte_eal_wait_lcore(reader_lcore_ids[i]) != 0) 373: 8b 7d 00 mov 0x0(%rbp),%edi 376: e8 00 00 00 00 callq 37b rc = TEST_FAILED; 37b: 85 c0 test %eax,%eax 37d: 45 0f 45 e5 cmovne %r13d,%r12d 381: 48 83 c3 10 add $0x10,%rbx 385: 48 83 c5 04 add $0x4,%rbp for (i = 0; i < num_readers; i++) { 389: 4c 39 f3 cmp %r14,%rbx 38c: 75 e2 jne 370 rte_free(data); 38e: 4c 89 ff mov %r15,%rdi 391: e8 00 00 00 00 callq 396 return rc; 396: 44 89 e0 mov %r12d,%eax 399: e9 cf fe ff ff jmpq 26d rte_eal_wait_lcore(worker_writer_lcore_id) != 0) 39e: 8b 7c 24 0c mov 0xc(%rsp),%edi if (writer_run(data) != 0 || 3a2: 45 31 e4 xor %r12d,%r12d rte_eal_wait_lcore(worker_writer_lcore_id) != 0) 3a5: e8 00 00 00 00 callq 3aa if (writer_run(data) != 0 || 3aa: 85 c0 test %eax,%eax 3ac: 41 0f 95 c4 setne %r12b 3b0: 41 f7 dc neg %r12d 3b3: eb 95 jmp 34a printf("Failed to allocate memory for seqlock data\n"); 3b5: bf 00 00 00 00 mov $0x0,%edi 3ba: e8 00 00 00 00 callq 3bf return TEST_FAILED; 3bf: b8 ff ff ff ff mov $0xffffffff,%eax 3c4: e9 a4 fe ff ff jmpq 26d Disassembly of section .text.startup: 0000000000000000 : { 0: bf 00 00 00 00 mov $0x0,%edi 5: e9 00 00 00 00 jmpq a <.LC2+0x2>