По этой причине и для обучения я хочу использовать Syscall Futex (2) Linux непосредственно, чтобы ждать и побудить в определенном условии. Подождите, ожидаемое значение должно быть рассчитано и передано в качестве параметра для Futex_wait < /code> syscall.
Для этого (с 1-байтовыми типами) мне нужно получить доступ к не связанной с внешней памяти, которая, вероятно, является неопределенным поведением (ub). < /p>
, что, вероятно, является неопределенным поведением (ub).
Код: Выделить всё
futex_wake
#include
#include
#include
#include
#include
#include
long futex(uint32_t* uaddr, int futex_op, uint32_t val,
const struct timespec* timeout, uint32_t* uaddr2, uint32_t val3) {
return syscall(SYS_futex, uaddr, futex_op, val, timeout, uaddr2, val3);
}
//! Get the 4-byte aligned pointer where uaddr is included.
uint32_t* calculate_futex_ptr(uint8_t* uaddr) {
const auto addr = reinterpret_cast(uaddr);
return reinterpret_cast(addr & ~(0x3));
}
//! Get offset (0-3) where uaddr is in relation to calculate_futex_ptr(uaddr).
int calculate_offset(uint8_t* uaddr) {
return reinterpret_cast(uaddr) & 0x3;
}
long futex_wake(uint8_t* uaddr) {
const auto futex_addr = calculate_futex_ptr(uaddr);
return futex(futex_addr, FUTEX_WAKE_PRIVATE, 123, nullptr, nullptr, 0);
}
long futex_wait(uint8_t* uaddr, uint8_t val) {
const auto futex_addr = calculate_futex_ptr(uaddr);
// Attention! Undefined behaviour.
uint32_t futex_val = *futex_addr;
// Inject val to correct location inside futex_val.
uint8_t* dest_addr = reinterpret_cast(&futex_val) + calculate_offset(uaddr);
*dest_addr = val;
return futex(futex_addr, FUTEX_WAIT_PRIVATE, futex_val, nullptr, nullptr, 0);
}
uint8_t before{6};
uint8_t wait_condition{1};
uint8_t after{5};
void thread_func() {
std::this_thread::sleep_for(std::chrono::seconds{1});
std::atomic_ref(wait_condition).store(3);
futex_wake(&wait_condition);
}
int main() {
std::thread thd(thread_func);
futex_wait(&wait_condition, 1);
thd.join();
}
< /code>
Мои вопросы: < /p>
- действительно ли отмеченная линия UB, и это единственная UB в этой программе? Стандартная библиотека имеет дело с проблемой?
Подробнее здесь: https://stackoverflow.com/questions/797 ... ded-for-fu