提交记录 48188
| 提交时间 |
评测时间 |
| 2026-09-16 13:05:21 |
2026-09-16 13:05:22 |
// duck.ac 1001 探针:验证裸 clone() 多线程在评测机上是否真并行 + mmap 400MB 是否可用。
// 判定:故意不排序(预期 WA),看报告的用时:
// ~600ms => 4 核并行 OK(3 个 worker + main 各自 spin 0.5s @ 3.6GHz)
// ~2.1s => clone 可用但被串行化
// RE => clone 崩溃(TLS/栈保护问题)
// 附加:mmap 400MB + 4KB 步长预触页 + 读校验,验证内存路径(约 +100~200ms)。
#include <cstdint>
#include <sched.h>
#include <sys/mman.h>
#include <immintrin.h>
extern "C" int clone(int (*)(void*), void*, int, void*, ...);
// 最小 TCB:glibc 栈保护读 fs:0x28,pointer guard 在 fs:0x30
struct TCB {
void* tcb;
void* dtv;
void* self;
long multiple_threads;
long gscope_flag;
void* sysinfo;
void* pad1;
unsigned long guard; // offset 0x28
unsigned long ptr_guard;
};
static char stacks[3][1 << 18] __attribute__((aligned(4096))); // 256KB/线程
static TCB tcbs[3] __attribute__((aligned(64)));
struct Arg {
volatile unsigned long long done;
unsigned long long spin_cycles;
} __attribute__((aligned(64)));
static Arg args[3];
static int worker(void* p) {
Arg* a = (Arg*)p;
unsigned long long end = __rdtsc() + a->spin_cycles;
while (__rdtsc() < end) {
}
__atomic_store_n(&a->done, 1, __ATOMIC_RELEASE);
return 0;
}
void sort(unsigned* a, int n) {
(void)a;
(void)n;
const unsigned long long SPIN = 1800000000ULL; // ~0.5s @ 3.6GHz
for (int t = 0; t < 3; ++t) {
args[t].spin_cycles = SPIN;
tcbs[t].tcb = &tcbs[t];
tcbs[t].self = &tcbs[t];
tcbs[t].multiple_threads = 1;
tcbs[t].guard = 0x1234567890ABCDEFUL;
tcbs[t].ptr_guard = 0xFEDCBA0987654321UL;
}
for (int t = 0; t < 3; ++t) {
void* top = stacks[t] + sizeof(stacks[t]);
clone(worker, top,
CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD |
CLONE_SYSVSEM | CLONE_SETTLS,
&args[t], nullptr, &tcbs[t], &tcbs[t]);
}
unsigned long long end = __rdtsc() + SPIN;
while (__rdtsc() < end) {
}
for (int t = 0; t < 3; ++t)
while (!__atomic_load_n(&args[t].done, __ATOMIC_ACQUIRE)) {
}
// 内存路径探测:mmap 400MB + 预触 + 读
volatile unsigned* v = (volatile unsigned*)mmap(
nullptr, 400000000UL, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
if (v != MAP_FAILED) {
for (size_t i = 0; i < 400000000UL; i += 4096) *(volatile char*)((char*)v + i) = 0;
unsigned s = 0;
for (size_t i = 0; i < 100000000UL; i += 1024) s += v[i];
if (s == 0xdeadbeef) *const_cast<unsigned*>(v) = s; // 防优化
}
}
| Compilation | N/A | N/A | Compile Error | Score: N/A | 显示更多 |
Judge Duck Online | 评测鸭在线
Server Time: 2026-09-20 14:36:25 | Loaded in 1 ms | Server Status
个人娱乐项目,仅供学习交流使用 | 捐赠