LCOV - code coverage report
Current view: top level - src - pl_thread_pthread.h (source / functions) Hit Total Coverage
Test: Code coverage Lines: 24 28 85.7 %
Date: 2025-03-29 09:04:10 Functions: 3 3 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 7 12 58.3 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * This file is part of libplacebo.
       3                 :            :  *
       4                 :            :  * libplacebo is free software; you can redistribute it and/or
       5                 :            :  * modify it under the terms of the GNU Lesser General Public
       6                 :            :  * License as published by the Free Software Foundation; either
       7                 :            :  * version 2.1 of the License, or (at your option) any later version.
       8                 :            :  *
       9                 :            :  * libplacebo is distributed in the hope that it will be useful,
      10                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12                 :            :  * GNU Lesser General Public License for more details.
      13                 :            :  *
      14                 :            :  * You should have received a copy of the GNU Lesser General Public
      15                 :            :  * License along with libplacebo. If not, see <http://www.gnu.org/licenses/>.
      16                 :            :  */
      17                 :            : 
      18                 :            : #pragma once
      19                 :            : 
      20                 :            : #include <errno.h>
      21                 :            : #include <pthread.h>
      22                 :            : #include <sys/time.h>
      23                 :            : #include <time.h>
      24                 :            : 
      25                 :            : #include <pl_assert.h>
      26                 :            : 
      27                 :            : typedef pthread_mutex_t pl_mutex;
      28                 :            : typedef pthread_cond_t  pl_cond;
      29                 :            : typedef pthread_mutex_t pl_static_mutex;
      30                 :            : typedef pthread_t       pl_thread;
      31                 :            : #define PL_STATIC_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
      32                 :            : 
      33                 :        140 : static inline int pl_mutex_init_type_internal(pl_mutex *mutex, enum pl_mutex_type mtype)
      34                 :            : {
      35                 :            :     int mutex_type;
      36         [ +  + ]:        140 :     switch (mtype) {
      37                 :            :         case PL_MUTEX_RECURSIVE:
      38                 :            :             mutex_type = PTHREAD_MUTEX_RECURSIVE;
      39                 :            :             break;
      40                 :        133 :         case PL_MUTEX_NORMAL:
      41                 :            :         default:
      42                 :            :         #ifndef NDEBUG
      43                 :            :             mutex_type = PTHREAD_MUTEX_ERRORCHECK;
      44                 :            :         #else
      45                 :            :             mutex_type = PTHREAD_MUTEX_DEFAULT;
      46                 :            :         #endif
      47                 :        133 :             break;
      48                 :            :     }
      49                 :            : 
      50                 :            :     int ret = 0;
      51                 :            :     pthread_mutexattr_t attr;
      52                 :        140 :     ret = pthread_mutexattr_init(&attr);
      53         [ +  - ]:        140 :     if (ret != 0)
      54                 :            :         return ret;
      55                 :            : 
      56                 :        140 :     pthread_mutexattr_settype(&attr, mutex_type);
      57                 :        140 :     ret = pthread_mutex_init(mutex, &attr);
      58                 :        140 :     pthread_mutexattr_destroy(&attr);
      59                 :        140 :     return ret;
      60                 :            : }
      61                 :            : 
      62                 :            : #define pl_mutex_init_type(mutex, mtype) \
      63                 :            :     pl_assert(!pl_mutex_init_type_internal(mutex, mtype))
      64                 :            : 
      65                 :            : #define pl_mutex_destroy    pthread_mutex_destroy
      66                 :            : #define pl_mutex_lock       pthread_mutex_lock
      67                 :            : #define pl_mutex_unlock     pthread_mutex_unlock
      68                 :            : 
      69                 :          4 : static inline int pl_cond_init(pl_cond *cond)
      70                 :            : {
      71                 :            :     int ret = 0;
      72                 :            :     pthread_condattr_t attr;
      73                 :          4 :     ret = pthread_condattr_init(&attr);
      74         [ +  - ]:          4 :     if (ret != 0)
      75                 :            :         return ret;
      76                 :            : 
      77                 :            : #ifdef PTHREAD_HAS_SETCLOCK
      78                 :          4 :     pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
      79                 :            : #endif
      80                 :          4 :     ret = pthread_cond_init(cond, &attr);
      81                 :          4 :     pthread_condattr_destroy(&attr);
      82                 :          4 :     return ret;
      83                 :            : }
      84                 :            : 
      85                 :            : #define pl_cond_destroy     pthread_cond_destroy
      86                 :            : #define pl_cond_broadcast   pthread_cond_broadcast
      87                 :            : #define pl_cond_signal      pthread_cond_signal
      88                 :            : #define pl_cond_wait        pthread_cond_wait
      89                 :            : 
      90                 :         72 : static inline int pl_cond_timedwait(pl_cond *cond, pl_mutex *mutex, uint64_t timeout)
      91                 :            : {
      92         [ -  + ]:         72 :     if (timeout == UINT64_MAX)
      93                 :          0 :         return pthread_cond_wait(cond, mutex);
      94                 :            : 
      95                 :            :     struct timespec ts;
      96                 :            : #ifdef PTHREAD_HAS_SETCLOCK
      97         [ -  + ]:         72 :     if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0)
      98                 :          0 :         return errno;
      99                 :            : #else
     100                 :            :     struct timeval tv;
     101                 :            :     if (gettimeofday(&tv, NULL) < 0) // equivalent to CLOCK_REALTIME
     102                 :            :         return errno;
     103                 :            :     ts.tv_sec = tv.tv_sec;
     104                 :            :     ts.tv_nsec = tv.tv_usec * 1000;
     105                 :            : #endif
     106                 :            : 
     107                 :         72 :     ts.tv_sec  += timeout / 1000000000LLU;
     108                 :         72 :     ts.tv_nsec += timeout % 1000000000LLU;
     109                 :            : 
     110         [ -  + ]:         72 :     if (ts.tv_nsec > 1000000000L) {
     111                 :          0 :         ts.tv_nsec -= 1000000000L;
     112                 :          0 :         ts.tv_sec++;
     113                 :            :     }
     114                 :            : 
     115                 :         72 :     return pthread_cond_timedwait(cond, mutex, &ts);
     116                 :            : }
     117                 :            : 
     118                 :            : #define pl_static_mutex_lock    pthread_mutex_lock
     119                 :            : #define pl_static_mutex_unlock  pthread_mutex_unlock
     120                 :            : 
     121                 :            : #define PL_THREAD_VOID void *
     122                 :            : #define PL_THREAD_RETURN() return NULL
     123                 :            : 
     124                 :            : #define pl_thread_create(t, f, a) pthread_create(t, NULL, f, a)
     125                 :            : #define pl_thread_join(t)         pthread_join(t, NULL)
     126                 :            : 
     127                 :            : static inline bool pl_thread_sleep(double t)
     128                 :            : {
     129                 :            :     if (t <= 0.0)
     130                 :            :         return true;
     131                 :            : 
     132                 :            :     struct timespec ts;
     133                 :            :     ts.tv_sec = (time_t) t;
     134                 :            :     ts.tv_nsec = (t - ts.tv_sec) * 1e9;
     135                 :            : 
     136                 :            :     return nanosleep(&ts, NULL) == 0;
     137                 :            : }

Generated by: LCOV version 1.16