68 lines · cpp
1#include <cinttypes>2#include <cstdint>3#include <cstdio>4#include <functional>5#include <mutex>6#include <thread>7 8std::mutex t1_mutex, t2_mutex;9 10struct test_data {11 uint32_t eax;12 uint32_t ebx;13 14 struct alignas(16) {15 uint8_t data[10];16 } st0;17};18 19constexpr test_data filler = {20 .eax = 0xffffffff,21 .ebx = 0xffffffff,22 .st0 = {{0x1f, 0x2f, 0x3f, 0x4f, 0x5f, 0x6f, 0x7f, 0x8f, 0x80, 0x40}},23};24 25void t_func(std::mutex &t_mutex) {26 std::lock_guard<std::mutex> t_lock(t_mutex);27 test_data out = filler;28 29 asm volatile(30 "finit\t\n"31 "fldt %2\t\n"32 "int3\n\t"33 "fstpt %2\t\n"34 : "+a"(out.eax), "+b"(out.ebx)35 : "m"(out.st0)36 : "memory", "st"37 );38 39 printf("eax = 0x%08" PRIx32 "\n", out.eax);40 printf("ebx = 0x%08" PRIx32 "\n", out.ebx);41 printf("st0 = { ");42 for (int i = 0; i < sizeof(out.st0.data); ++i)43 printf("0x%02" PRIx8 " ", out.st0.data[i]);44 printf("}\n");45}46 47int main() {48 // block both threads from proceeding49 std::unique_lock<std::mutex> m1_lock(t1_mutex);50 std::unique_lock<std::mutex> m2_lock(t2_mutex);51 52 // start both threads53 std::thread t1(t_func, std::ref(t1_mutex));54 std::thread t2(t_func, std::ref(t2_mutex));55 56 // release lock on thread 1 to make it interrupt the program57 m1_lock.unlock();58 // wait for thread 1 to finish59 t1.join();60 61 // release lock on thread 262 m2_lock.unlock();63 // wait for thread 2 to finish64 t2.join();65 66 return 0;67}68