#include "portable.h" #include "common.h" #include int64_t portable_now_ms(void){ struct timespec ts; if(clock_gettime(CLOCK_MONOTONIC, &ts)!=0){ /* CLOCK_MONOTONIC always present on Pi5 kernel 6.x; fallback guard */ clock_gettime(CLOCK_REALTIME, &ts); } return (int64_t)ts.tv_sec*1000 + ts.tv_nsec/1000000; } void portable_sleep_ms(int ms){ if(ms<=0) return; struct timespec req, rem; req.tv_sec = ms/1000; req.tv_nsec = (long)(ms%1000)*1000000L; while(nanosleep(&req,&rem)==-1 && errno==EINTR){ req=rem; req.tv_nsec%=1000000000L; } } int portable_thread_create(pthread_t *t, void*(*fn)(void*), void*arg, size_t stack_bytes){ pthread_attr_t attr; if(pthread_attr_init(&attr)!=0) return FAILURE; if(stack_bytes>0){ size_t ps = sysconf(_SC_PAGESIZE); if(ps<1) ps=4096; size_t st = (stack_bytes + ps-1) & ~(size_t)(ps-1); if(st < (size_t)PTHREAD_STACK_MIN) st = (size_t)PTHREAD_STACK_MIN; if(pthread_attr_setstacksize(&attr, st)!=0){ pthread_attr_destroy(&attr); return FAILURE; } } pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); int rc = pthread_create(t,&attr,fn,arg); pthread_attr_destroy(&attr); return rc==0?SUCCESS:FAILURE; }