Coverage Report

Created: 2025-08-26 06:40

/src/libusb/libusb/os/threads_posix.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * libusb synchronization using POSIX Threads
3
 *
4
 * Copyright © 2011 Vitali Lovich <vlovich@aliph.com>
5
 * Copyright © 2011 Peter Stuge <peter@stuge.se>
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
22
#include "libusbi.h"
23
24
#include <errno.h>
25
#include <limits.h>
26
#if defined(__ANDROID__)
27
# include <unistd.h>
28
#elif defined(__HAIKU__)
29
# include <os/kernel/OS.h>
30
#elif defined(__linux__)
31
# include <sys/syscall.h>
32
# include <unistd.h>
33
#elif defined(__NetBSD__)
34
# include <lwp.h>
35
#elif defined(__OpenBSD__)
36
# include <unistd.h>
37
#elif defined(__sun__)
38
# include <sys/lwp.h>
39
#endif
40
41
void usbi_cond_init(pthread_cond_t *cond)
42
0
{
43
0
#ifdef HAVE_PTHREAD_CONDATTR_SETCLOCK
44
0
  pthread_condattr_t condattr;
45
46
0
  PTHREAD_CHECK(pthread_condattr_init(&condattr));
47
0
  PTHREAD_CHECK(pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC));
48
0
  PTHREAD_CHECK(pthread_cond_init(cond, &condattr));
49
0
  PTHREAD_CHECK(pthread_condattr_destroy(&condattr));
50
#else
51
  PTHREAD_CHECK(pthread_cond_init(cond, NULL));
52
#endif
53
0
}
54
55
int usbi_cond_timedwait(pthread_cond_t *cond,
56
  pthread_mutex_t *mutex, const struct timeval *tv)
57
0
{
58
0
  struct timespec timeout;
59
0
  int r;
60
61
0
#ifdef HAVE_PTHREAD_CONDATTR_SETCLOCK
62
0
  usbi_get_monotonic_time(&timeout);
63
#else
64
  usbi_get_real_time(&timeout);
65
#endif
66
67
0
  timeout.tv_sec += tv->tv_sec;
68
0
  timeout.tv_nsec += tv->tv_usec * 1000L;
69
0
  if (timeout.tv_nsec >= NSEC_PER_SEC) {
70
0
    timeout.tv_nsec -= NSEC_PER_SEC;
71
0
    timeout.tv_sec++;
72
0
  }
73
74
0
  r = pthread_cond_timedwait(cond, mutex, &timeout);
75
0
  if (r == 0)
76
0
    return 0;
77
0
  else if (r == ETIMEDOUT)
78
0
    return LIBUSB_ERROR_TIMEOUT;
79
0
  else
80
0
    return LIBUSB_ERROR_OTHER;
81
0
}
82
83
unsigned long usbi_get_tid(void)
84
0
{
85
0
  static _Thread_local unsigned long tl_tid;
86
0
  unsigned long tid;
87
88
0
  if (tl_tid)
89
0
    return tl_tid;
90
91
#if defined(__ANDROID__)
92
  tid = (unsigned long)gettid();
93
#elif defined(__APPLE__)
94
#ifdef HAVE_PTHREAD_THREADID_NP
95
  uint64_t thread_id;
96
97
  if (pthread_threadid_np(NULL, &thread_id) == 0)
98
    tid = (unsigned long)thread_id;
99
  else
100
    tid = ULONG_MAX;
101
#else
102
  tid = (unsigned long)pthread_mach_thread_np(pthread_self());
103
#endif
104
#elif defined(__HAIKU__)
105
  tid = (unsigned long)get_pthread_thread_id(pthread_self());
106
#elif defined(__linux__)
107
0
  tid = (unsigned long)syscall(SYS_gettid);
108
#elif defined(__NetBSD__)
109
  tid = (unsigned long)_lwp_self();
110
#elif defined(__OpenBSD__)
111
  tid = (unsigned long)getthrid();
112
#elif defined(__sun__)
113
  tid = (unsigned long)_lwp_self();
114
#else
115
  tid = ULONG_MAX;
116
#endif
117
118
0
  if (tid == ULONG_MAX) {
119
    /* If we don't have a thread ID, at least return a unique
120
     * value that can be used to distinguish individual
121
     * threads. */
122
0
    tid = (unsigned long)(uintptr_t)pthread_self();
123
0
  }
124
125
0
  return tl_tid = tid;
126
0
}