summaryrefslogtreecommitdiff
path: root/src/util/thread/thread_linux.c
blob: c9edce5a023c7c62920aa1de484bfcc285ed4fa8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include <al/types.h>

#include "../error.h"

#include "thread.h"

void nn_thread_sleep(nn_os_tstamp delay)
{
    struct timespec tv;
    tv.tv_sec = (s64)delay;
    tv.tv_nsec = (s64)((delay - tv.tv_sec) * 1e9);
    while (nanosleep(&tv, &tv) == -1 && errno == EINTR) {}
}

void nn_thread_create(struct nn_thread *thread, nn_thread_func func, void *userdata)
{
    s32 ret = pthread_create(&thread->thread, NULL, func, userdata);
    al_assert(ret == 0);
}

void nn_thread_set_priority(s32 policy, s32 priority)
{
    struct sched_param params = { 0 };
    params.sched_priority = priority;
    pthread_setschedparam(pthread_self(), policy, &params);
}

void nn_thread_set_name(const char *name)
{
    s32 ret = pthread_setname_np(pthread_self(), name);
    al_assert(ret != ERANGE);
}

void nn_thread_join(struct nn_thread *thread)
{
    pthread_join(thread->thread, NULL);
}

#ifdef NAUNET_HAS_THREAD_CANCEL
void nn_thread_cancel(struct nn_thread *thread)
{
    pthread_cancel(thread->thread);
}

void nn_thread_setcanceltype(s32 type)
{
    pthread_setcanceltype(type, NULL);
}
#endif

/*
void nn_thread_detach(struct nn_thread *thread)
{
    pthread_detach(thread->thread);
}
*/

void nn_mutex_init(struct nn_mutex *mutex)
{
    s32 ret = pthread_mutex_init(&mutex->mutex, NULL);
    // Linux manpage says this always returns 0.
    al_assert(ret == 0);
}

s32 nn_mutex_lock(struct nn_mutex *mutex)
{
    s32 ret = pthread_mutex_lock(&mutex->mutex);
    al_assert(ret != EINVAL);
    return ret;
}

s32 nn_mutex_unlock(struct nn_mutex *mutex)
{
    s32 ret = pthread_mutex_unlock(&mutex->mutex);
    al_assert(ret != EINVAL);
    return ret;
}

void nn_mutex_destroy(struct nn_mutex *mutex)
{
    s32 ret = pthread_mutex_destroy(&mutex->mutex);
    al_assert(ret != EBUSY);
}

void nn_cond_init(struct nn_cond *cond)
{
    cond->condition = true;
    pthread_cond_init(&cond->cond, NULL);
}

void nn_cond_wait(struct nn_cond *cond, struct nn_mutex *mutex)
{
    cond->condition = false;
    do {
        pthread_cond_wait(&cond->cond, &mutex->mutex);
    } while (!cond->condition);
}

bool nn_cond_is_waiting(struct nn_cond *cond)
{
    return !cond->condition;
}

void nn_cond_signal(struct nn_cond *cond)
{
    cond->condition = true;
    pthread_cond_signal(&cond->cond);
}

void nn_cond_destroy(struct nn_cond *cond)
{
    s32 ret = pthread_cond_destroy(&cond->cond);
    al_assert(ret != EBUSY);
}