2 * Wrappers around mutex/cond/thread functions
4 * Copyright Red Hat, Inc. 2009
7 * Marcelo Tosatti <mtosatti@redhat.com>
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
20 #include "qemu-thread.h"
22 static void error_exit(int err
, const char *msg
)
24 fprintf(stderr
, "qemu: %s: %s\n", msg
, strerror(err
));
28 void qemu_mutex_init(QemuMutex
*mutex
)
31 pthread_mutexattr_t mutexattr
;
33 pthread_mutexattr_init(&mutexattr
);
34 pthread_mutexattr_settype(&mutexattr
, PTHREAD_MUTEX_ERRORCHECK
);
35 err
= pthread_mutex_init(&mutex
->lock
, &mutexattr
);
36 pthread_mutexattr_destroy(&mutexattr
);
38 error_exit(err
, __func__
);
41 void qemu_mutex_destroy(QemuMutex
*mutex
)
45 err
= pthread_mutex_destroy(&mutex
->lock
);
47 error_exit(err
, __func__
);
50 void qemu_mutex_lock(QemuMutex
*mutex
)
54 err
= pthread_mutex_lock(&mutex
->lock
);
56 error_exit(err
, __func__
);
59 int qemu_mutex_trylock(QemuMutex
*mutex
)
61 return pthread_mutex_trylock(&mutex
->lock
);
64 static void timespec_add_ms(struct timespec
*ts
, uint64_t msecs
)
66 ts
->tv_sec
= ts
->tv_sec
+ (long)(msecs
/ 1000);
67 ts
->tv_nsec
= (ts
->tv_nsec
+ ((long)msecs
% 1000) * 1000000);
68 if (ts
->tv_nsec
>= 1000000000) {
69 ts
->tv_nsec
-= 1000000000;
74 int qemu_mutex_timedlock(QemuMutex
*mutex
, uint64_t msecs
)
79 clock_gettime(CLOCK_REALTIME
, &ts
);
80 timespec_add_ms(&ts
, msecs
);
82 err
= pthread_mutex_timedlock(&mutex
->lock
, &ts
);
83 if (err
&& err
!= ETIMEDOUT
)
84 error_exit(err
, __func__
);
88 void qemu_mutex_unlock(QemuMutex
*mutex
)
92 err
= pthread_mutex_unlock(&mutex
->lock
);
94 error_exit(err
, __func__
);
97 void qemu_cond_init(QemuCond
*cond
)
101 err
= pthread_cond_init(&cond
->cond
, NULL
);
103 error_exit(err
, __func__
);
106 void qemu_cond_destroy(QemuCond
*cond
)
110 err
= pthread_cond_destroy(&cond
->cond
);
112 error_exit(err
, __func__
);
115 void qemu_cond_signal(QemuCond
*cond
)
119 err
= pthread_cond_signal(&cond
->cond
);
121 error_exit(err
, __func__
);
124 void qemu_cond_broadcast(QemuCond
*cond
)
128 err
= pthread_cond_broadcast(&cond
->cond
);
130 error_exit(err
, __func__
);
133 void qemu_cond_wait(QemuCond
*cond
, QemuMutex
*mutex
)
137 err
= pthread_cond_wait(&cond
->cond
, &mutex
->lock
);
139 error_exit(err
, __func__
);
142 int qemu_cond_timedwait(QemuCond
*cond
, QemuMutex
*mutex
, uint64_t msecs
)
147 clock_gettime(CLOCK_REALTIME
, &ts
);
148 timespec_add_ms(&ts
, msecs
);
150 err
= pthread_cond_timedwait(&cond
->cond
, &mutex
->lock
, &ts
);
151 if (err
&& err
!= ETIMEDOUT
)
152 error_exit(err
, __func__
);
156 void qemu_thread_create(QemuThread
*thread
,
157 void *(*start_routine
)(void*),
162 /* Leave signal handling to the iothread. */
163 sigset_t set
, oldset
;
166 pthread_sigmask(SIG_SETMASK
, &set
, &oldset
);
167 err
= pthread_create(&thread
->thread
, NULL
, start_routine
, arg
);
169 error_exit(err
, __func__
);
171 pthread_sigmask(SIG_SETMASK
, &oldset
, NULL
);
174 void qemu_thread_get_self(QemuThread
*thread
)
176 thread
->thread
= pthread_self();
179 int qemu_thread_is_self(QemuThread
*thread
)
181 return pthread_equal(pthread_self(), thread
->thread
);
184 void qemu_thread_exit(void *retval
)
186 pthread_exit(retval
);