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: 0f 85 a3 00 00 00 jne d3 30: 45 85 e4 test %r12d,%r12d 33: 0f 85 ac 00 00 00 jne e5 uint32_t sn; uint64_t a; uint64_t b; uint64_t c; interrupted = rte_rand_max(INTERRUPTED_READER_FREQUENCY) == 0; 39: bf e8 03 00 00 mov $0x3e8,%edi struct data *data = r->data; 3e: 49 8b 1e mov (%r14),%rbx interrupted = rte_rand_max(INTERRUPTED_READER_FREQUENCY) == 0; 41: e8 00 00 00 00 callq 46 46: 49 89 c5 mov %rax,%r13 49: eb 27 jmp 72 4b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) 50: 48 8b 7b 08 mov 0x8(%rbx),%rdi 54: 48 8b 8b 80 00 00 00 mov 0x80(%rbx),%rcx 5b: 48 8b 53 40 mov 0x40(%rbx),%rdx { /* __ATOMIC_ACQUIRE to prevent loads after (in program order) * from happening before the sn load. Synchronizes-with the * store release in rte_seqcount_write_end(). */ return __atomic_load_n(&seqcount->sn, __ATOMIC_ACQUIRE); 5f: 8b 2b mov (%rbx),%ebp do { sn = rte_seqlock_read_begin(&data->lock); a = data->a; 61: 49 89 ff mov %rdi,%r15 /* 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)) 64: 40 f6 c5 01 test $0x1,%bpl 68: 75 f5 jne 5f 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); 6a: 44 8b 03 mov (%rbx),%r8d if (interrupted) rte_delay_us_block(READER_INTERRUPT_TIME); c = data->c; b = data->b; } while (rte_seqlock_read_retry(&data->lock, sn)); 6d: 44 39 c5 cmp %r8d,%ebp 70: 74 2e je a0 72: 4d 85 ed test %r13,%r13 75: 75 d9 jne 50 return __atomic_load_n(&seqcount->sn, __ATOMIC_ACQUIRE); 77: 8b 2b mov (%rbx),%ebp rte_delay_us_block(READER_INTERRUPT_TIME); 79: bf e8 03 00 00 mov $0x3e8,%edi a = data->a; 7e: 4c 8b 7b 08 mov 0x8(%rbx),%r15 rte_delay_us_block(READER_INTERRUPT_TIME); 82: e8 00 00 00 00 callq 87 c = data->c; 87: 48 8b 8b 80 00 00 00 mov 0x80(%rbx),%rcx b = data->b; 8e: 48 8b 53 40 mov 0x40(%rbx),%rdx if (unlikely(begin_sn & 1)) 92: 40 f6 c5 01 test $0x1,%bpl 96: 75 df jne 77 end_sn = __atomic_load_n(&seqcount->sn, __ATOMIC_RELAXED); 98: 44 8b 03 mov (%rbx),%r8d } while (rte_seqlock_read_retry(&data->lock, sn)); 9b: 44 39 c5 cmp %r8d,%ebp 9e: 75 d2 jne 72 if (a != b || b != c) { a0: 48 39 d1 cmp %rdx,%rcx a3: 75 09 jne ae a5: 49 39 d7 cmp %rdx,%r15 a8: 0f 84 72 ff ff ff je 20 printf("Reader observed inconsistent data values " ae: 31 c0 xor %eax,%eax b0: 4c 89 fe mov %r15,%rsi b3: bf 00 00 00 00 mov $0x0,%edi b8: e8 00 00 00 00 callq bd while (__atomic_load_n(&r->stop, __ATOMIC_RELAXED) == 0 && bd: 48 8b 44 24 08 mov 0x8(%rsp),%rax "%" PRIu64 " %" PRIu64 " %" PRIu64 "\n", a, b, c); rc = TEST_FAILED; c2: 41 bc ff ff ff ff mov $0xffffffff,%r12d while (__atomic_load_n(&r->stop, __ATOMIC_RELAXED) == 0 && c8: 0f b6 00 movzbl (%rax),%eax cb: 84 c0 test %al,%al cd: 0f 84 5d ff ff ff je 30 } } return rc; } d3: 48 83 c4 18 add $0x18,%rsp d7: 44 89 e0 mov %r12d,%eax da: 5b pop %rbx db: 5d pop %rbp dc: 41 5c pop %r12 de: 41 5d pop %r13 e0: 41 5e pop %r14 e2: 41 5f pop %r15 e4: c3 retq e5: 41 bc ff ff ff ff mov $0xffffffff,%r12d eb: eb e6 jmp d3 ed: 0f 1f 00 nopl (%rax) 00000000000000f0 : { f0: 41 55 push %r13 f2: 41 54 push %r12 f4: 55 push %rbp f5: 53 push %rbx f6: 48 89 fb mov %rdi,%rbx f9: 48 83 ec 08 sub $0x8,%rsp "c"(0x10000)); return tsc.tsc_64; } #endif asm volatile("rdtsc" : fd: 0f 31 rdtsc ff: 48 c1 e2 20 shl $0x20,%rdx 103: 89 c5 mov %eax,%ebp 105: 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(); 108: e8 00 00 00 00 callq 10d WRITER_RUNTIME * rte_get_timer_hz(); 10d: 48 85 c0 test %rax,%rax 110: 0f 88 0a 01 00 00 js 220 deadline = rte_get_timer_cycles() + 116: 48 85 ed test %rbp,%rbp WRITER_RUNTIME * rte_get_timer_hz(); 119: c4 e1 f3 2a c8 vcvtsi2sd %rax,%xmm1,%xmm1 deadline = rte_get_timer_cycles() + 11e: 0f 88 1a 01 00 00 js 23e 124: c4 e1 fb 2a c5 vcvtsi2sd %rbp,%xmm0,%xmm0 129: c4 e2 f1 b9 05 00 00 vfmadd231sd 0x0(%rip),%xmm1,%xmm0 # 132 130: 00 00 132: c5 fb 10 0d 00 00 00 vmovsd 0x0(%rip),%xmm1 # 13a 139: 00 13a: c5 f9 2e c1 vucomisd %xmm1,%xmm0 13e: 0f 83 bc 00 00 00 jae 200 144: c4 61 fb 2c e8 vcvttsd2si %xmm0,%r13 149: 0f 31 rdtsc 14b: 48 c1 e2 20 shl $0x20,%rdx 14f: 89 c0 mov %eax,%eax 151: 4c 8d 63 04 lea 0x4(%rbx),%r12 155: 48 09 d0 or %rdx,%rax while (rte_get_timer_cycles() < deadline) { 158: 49 39 c5 cmp %rax,%r13 15b: 77 3d ja 19a 15d: e9 8e 00 00 00 jmpq 1f0 162: 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; 168: 8b 03 mov (%rbx),%eax data->a = new_value; 16a: 48 89 6b 08 mov %rbp,0x8(%rbx) 16e: 83 c0 01 add $0x1,%eax /* Synchronizes-with the load acquire in rte_seqcount_read_begin(). */ __atomic_store_n(&seqcount->sn, sn, __ATOMIC_RELEASE); 171: 89 03 mov %eax,(%rbx) static inline void rte_spinlock_unlock (rte_spinlock_t *sl) { int unlock_val = 0; asm volatile ( 173: 31 c0 xor %eax,%eax 175: 41 87 04 24 xchg %eax,(%r12) delay = rte_rand_max(WRITER_MAX_DELAY); 179: bf 64 00 00 00 mov $0x64,%edi 17e: e8 00 00 00 00 callq 183 rte_delay_us_block(delay); 183: 89 c7 mov %eax,%edi 185: e8 00 00 00 00 callq 18a 18a: 0f 31 rdtsc 18c: 48 c1 e2 20 shl $0x20,%rdx 190: 89 c0 mov %eax,%eax 192: 48 09 d0 or %rdx,%rax while (rte_get_timer_cycles() < deadline) { 195: 49 39 c5 cmp %rax,%r13 198: 76 56 jbe 1f0 new_value = rte_rand(); 19a: e8 00 00 00 00 callq 19f interrupted = rte_rand_max(INTERRUPTED_WRITER_FREQUENCY) == 0; 19f: bf e8 03 00 00 mov $0x3e8,%edi new_value = rte_rand(); 1a4: 48 89 c5 mov %rax,%rbp interrupted = rte_rand_max(INTERRUPTED_WRITER_FREQUENCY) == 0; 1a7: e8 00 00 00 00 callq 1ac asm volatile ( 1ac: ba 01 00 00 00 mov $0x1,%edx 1b1: 41 87 14 24 xchg %edx,(%r12) 1b5: 85 d2 test %edx,%edx 1b7: 74 0b je 1c4 1b9: f3 90 pause 1bb: 41 83 3c 24 00 cmpl $0x0,(%r12) 1c0: 75 f7 jne 1b9 1c2: eb ed jmp 1b1 sn = seqcount->sn + 1; 1c4: 8b 0b mov (%rbx),%ecx if (interrupted) 1c6: 48 85 c0 test %rax,%rax 1c9: 8d 51 01 lea 0x1(%rcx),%edx __atomic_store_n(&seqcount->sn, sn, __ATOMIC_RELAXED); 1cc: 89 13 mov %edx,(%rbx) data->c = new_value; 1ce: 48 89 ab 80 00 00 00 mov %rbp,0x80(%rbx) data->b = new_value; 1d5: 48 89 6b 40 mov %rbp,0x40(%rbx) if (interrupted) 1d9: 75 8d jne 168 rte_delay_us_block(WRITER_INTERRUPT_TIME); 1db: bf 01 00 00 00 mov $0x1,%edi 1e0: e8 00 00 00 00 callq 1e5 1e5: eb 81 jmp 168 1e7: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1) 1ee: 00 00 } 1f0: 48 83 c4 08 add $0x8,%rsp 1f4: 31 c0 xor %eax,%eax 1f6: 5b pop %rbx 1f7: 5d pop %rbp 1f8: 41 5c pop %r12 1fa: 41 5d pop %r13 1fc: c3 retq 1fd: 0f 1f 00 nopl (%rax) deadline = rte_get_timer_cycles() + 200: c5 fb 5c c1 vsubsd %xmm1,%xmm0,%xmm0 204: 48 b8 00 00 00 00 00 movabs $0x8000000000000000,%rax 20b: 00 00 80 20e: c4 61 fb 2c e8 vcvttsd2si %xmm0,%r13 213: 49 31 c5 xor %rax,%r13 216: e9 2e ff ff ff jmpq 149 21b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) WRITER_RUNTIME * rte_get_timer_hz(); 220: 48 89 c2 mov %rax,%rdx 223: 83 e0 01 and $0x1,%eax 226: 48 d1 ea shr %rdx 229: 48 09 c2 or %rax,%rdx deadline = rte_get_timer_cycles() + 22c: 48 85 ed test %rbp,%rbp WRITER_RUNTIME * rte_get_timer_hz(); 22f: c4 e1 f3 2a ca vcvtsi2sd %rdx,%xmm1,%xmm1 234: c5 f3 58 c9 vaddsd %xmm1,%xmm1,%xmm1 deadline = rte_get_timer_cycles() + 238: 0f 89 e6 fe ff ff jns 124 23e: 48 89 e8 mov %rbp,%rax 241: 83 e5 01 and $0x1,%ebp 244: 48 d1 e8 shr %rax 247: 48 09 e8 or %rbp,%rax 24a: c4 e1 fb 2a c0 vcvtsi2sd %rax,%xmm0,%xmm0 24f: c5 fb 58 c0 vaddsd %xmm0,%xmm0,%xmm0 253: e9 d1 fe ff ff jmpq 129 258: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1) 25f: 00 0000000000000260 : /* Only a compile-time test */ static rte_seqlock_t __rte_unused static_init_lock = RTE_SEQLOCK_INITIALIZER; static int test_seqlock(void) { 260: 41 57 push %r15 262: 41 56 push %r14 264: 41 55 push %r13 266: 41 54 push %r12 268: 55 push %rbp 269: 53 push %rbx 26a: 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(); 271: e8 00 00 00 00 callq 276 if (num_lcores < MIN_LCORE_COUNT) { 276: 83 f8 03 cmp $0x3,%eax num_lcores = rte_lcore_count(); 279: 41 89 c6 mov %eax,%r14d if (num_lcores < MIN_LCORE_COUNT) { 27c: 77 22 ja 2a0 printf("Too few cores to run test. Skipping.\n"); 27e: bf 00 00 00 00 mov $0x0,%edi 283: e8 00 00 00 00 callq 288 return TEST_SKIPPED; 288: b8 4d 00 00 00 mov $0x4d,%eax } rte_free(data); return rc; } 28d: 48 81 c4 18 0a 00 00 add $0xa18,%rsp 294: 5b pop %rbx 295: 5d pop %rbp 296: 41 5c pop %r12 298: 41 5d pop %r13 29a: 41 5e pop %r14 29c: 41 5f pop %r15 29e: c3 retq 29f: 90 nop data = rte_zmalloc(NULL, sizeof(struct data), 0); 2a0: 31 d2 xor %edx,%edx 2a2: 31 ff xor %edi,%edi 2a4: be c0 00 00 00 mov $0xc0,%esi 2a9: e8 00 00 00 00 callq 2ae if (data == NULL) { 2ae: 48 85 c0 test %rax,%rax data = rte_zmalloc(NULL, sizeof(struct data), 0); 2b1: 49 89 c7 mov %rax,%r15 if (data == NULL) { 2b4: 0f 84 1b 01 00 00 je 3d5 RTE_LCORE_FOREACH_WORKER(lcore_id) { 2ba: 31 d2 xor %edx,%edx 2bc: be 01 00 00 00 mov $0x1,%esi 2c1: bf ff ff ff ff mov $0xffffffff,%edi 2c6: e8 00 00 00 00 callq 2cb 2cb: 83 f8 7f cmp $0x7f,%eax 2ce: 89 c3 mov %eax,%ebx unsigned int worker_writer_lcore_id = 0; 2d0: c7 44 24 0c 00 00 00 movl $0x0,0xc(%rsp) 2d7: 00 RTE_LCORE_FOREACH_WORKER(lcore_id) { 2d8: 77 6f ja 349 i = 0; 2da: 45 31 e4 xor %r12d,%r12d 2dd: 4c 8d ac 24 10 02 00 lea 0x210(%rsp),%r13 2e4: 00 2e5: eb 35 jmp 31c 2e7: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1) 2ee: 00 00 rte_eal_remote_launch(writer_run, data, lcore_id); 2f0: 89 da mov %ebx,%edx 2f2: 4c 89 fe mov %r15,%rsi 2f5: bf 00 00 00 00 mov $0x0,%edi 2fa: e8 00 00 00 00 callq 2ff 2ff: 89 5c 24 0c mov %ebx,0xc(%rsp) RTE_LCORE_FOREACH_WORKER(lcore_id) { 303: 31 d2 xor %edx,%edx 305: 89 df mov %ebx,%edi 307: be 01 00 00 00 mov $0x1,%esi 30c: e8 00 00 00 00 callq 311 i++; 311: 41 83 c4 01 add $0x1,%r12d RTE_LCORE_FOREACH_WORKER(lcore_id) { 315: 83 f8 7f cmp $0x7f,%eax 318: 89 c3 mov %eax,%ebx 31a: 77 3c ja 358 if (i == 0) { 31c: 45 85 e4 test %r12d,%r12d 31f: 74 cf je 2f0 struct reader *reader = &readers[reader_idx]; 321: 41 8d 6c 24 ff lea -0x1(%r12),%ebp rte_eal_remote_launch(reader_run, reader, lcore_id); 326: 89 da mov %ebx,%edx 328: bf 00 00 00 00 mov $0x0,%edi struct reader *reader = &readers[reader_idx]; 32d: 48 89 ee mov %rbp,%rsi 330: 48 c1 e6 04 shl $0x4,%rsi 334: 4c 01 ee add %r13,%rsi reader->data = data; 337: 4c 89 3e mov %r15,(%rsi) reader->stop = 0; 33a: c6 46 08 00 movb $0x0,0x8(%rsi) rte_eal_remote_launch(reader_run, reader, lcore_id); 33e: e8 00 00 00 00 callq 343 reader_lcore_ids[reader_idx] = lcore_id; 343: 89 5c ac 10 mov %ebx,0x10(%rsp,%rbp,4) 347: eb ba jmp 303 349: 4c 8d ac 24 10 02 00 lea 0x210(%rsp),%r13 350: 00 351: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) if (writer_run(data) != 0 || 358: 4c 89 ff mov %r15,%rdi rc = TEST_FAILED; 35b: 41 bc ff ff ff ff mov $0xffffffff,%r12d if (writer_run(data) != 0 || 361: e8 8a fd ff ff callq f0 366: 85 c0 test %eax,%eax 368: 74 54 je 3be 36a: 41 8d 46 fd lea -0x3(%r14),%eax 36e: 48 8d 6c 24 10 lea 0x10(%rsp),%rbp 373: 49 8d 5d 08 lea 0x8(%r13),%rbx 377: 48 c1 e0 04 shl $0x4,%rax 37b: 4d 8d 74 05 18 lea 0x18(%r13,%rax,1),%r14 rc = TEST_FAILED; 380: 41 bd ff ff ff ff mov $0xffffffff,%r13d 386: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 38d: 00 00 00 __atomic_store_n(&reader->stop, 1, __ATOMIC_RELAXED); 390: c6 03 01 movb $0x1,(%rbx) if (rte_eal_wait_lcore(reader_lcore_ids[i]) != 0) 393: 8b 7d 00 mov 0x0(%rbp),%edi 396: e8 00 00 00 00 callq 39b rc = TEST_FAILED; 39b: 85 c0 test %eax,%eax 39d: 45 0f 45 e5 cmovne %r13d,%r12d 3a1: 48 83 c3 10 add $0x10,%rbx 3a5: 48 83 c5 04 add $0x4,%rbp for (i = 0; i < num_readers; i++) { 3a9: 4c 39 f3 cmp %r14,%rbx 3ac: 75 e2 jne 390 rte_free(data); 3ae: 4c 89 ff mov %r15,%rdi 3b1: e8 00 00 00 00 callq 3b6 return rc; 3b6: 44 89 e0 mov %r12d,%eax 3b9: e9 cf fe ff ff jmpq 28d rte_eal_wait_lcore(worker_writer_lcore_id) != 0) 3be: 8b 7c 24 0c mov 0xc(%rsp),%edi if (writer_run(data) != 0 || 3c2: 45 31 e4 xor %r12d,%r12d rte_eal_wait_lcore(worker_writer_lcore_id) != 0) 3c5: e8 00 00 00 00 callq 3ca if (writer_run(data) != 0 || 3ca: 85 c0 test %eax,%eax 3cc: 41 0f 95 c4 setne %r12b 3d0: 41 f7 dc neg %r12d 3d3: eb 95 jmp 36a printf("Failed to allocate memory for seqlock data\n"); 3d5: bf 00 00 00 00 mov $0x0,%edi 3da: e8 00 00 00 00 callq 3df return TEST_FAILED; 3df: b8 ff ff ff ff mov $0xffffffff,%eax 3e4: e9 a4 fe ff ff jmpq 28d 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>