portable.c 1.2 KB

1234567891011121314151617181920212223242526272829303132333435
  1. #include "portable.h"
  2. #include "common.h"
  3. #include <time.h>
  4. int64_t portable_now_ms(void){
  5. struct timespec ts;
  6. if(clock_gettime(CLOCK_MONOTONIC, &ts)!=0){
  7. /* CLOCK_MONOTONIC always present on Pi5 kernel 6.x; fallback guard */
  8. clock_gettime(CLOCK_REALTIME, &ts);
  9. }
  10. return (int64_t)ts.tv_sec*1000 + ts.tv_nsec/1000000;
  11. }
  12. void portable_sleep_ms(int ms){
  13. if(ms<=0) return;
  14. struct timespec req, rem;
  15. req.tv_sec = ms/1000;
  16. req.tv_nsec = (long)(ms%1000)*1000000L;
  17. while(nanosleep(&req,&rem)==-1 && errno==EINTR){ req=rem; req.tv_nsec%=1000000000L; }
  18. }
  19. int portable_thread_create(pthread_t *t, void*(*fn)(void*), void*arg, size_t stack_bytes){
  20. pthread_attr_t attr;
  21. if(pthread_attr_init(&attr)!=0) return FAILURE;
  22. if(stack_bytes>0){
  23. size_t ps = sysconf(_SC_PAGESIZE); if(ps<1) ps=4096;
  24. size_t st = (stack_bytes + ps-1) & ~(size_t)(ps-1);
  25. if(st < (size_t)PTHREAD_STACK_MIN) st = (size_t)PTHREAD_STACK_MIN;
  26. if(pthread_attr_setstacksize(&attr, st)!=0){ pthread_attr_destroy(&attr); return FAILURE; }
  27. }
  28. pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
  29. int rc = pthread_create(t,&attr,fn,arg);
  30. pthread_attr_destroy(&attr);
  31. return rc==0?SUCCESS:FAILURE;
  32. }