File: | src/lib/librthread/rthread_barrier.c |
Warning: | line 113, column 7 Although the value stored to 'rc' is used in the enclosing expression, the value is never actually read from 'rc' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: rthread_barrier.c,v 1.5 2020/04/06 00:01:08 pirofti Exp $ */ |
2 | /* |
3 | * Copyright (c) 2012 Paul Irofti <paul@irofti.net> |
4 | * |
5 | * Permission to use, copy, modify, and/or distribute this software for any |
6 | * purpose with or without fee is hereby granted, provided that the above |
7 | * copyright notice and this permission notice appear in all copies. |
8 | * |
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
16 | */ |
17 | |
18 | #include <errno(*__errno()).h> |
19 | #include <stdlib.h> |
20 | |
21 | #include <pthread.h> |
22 | |
23 | #include "rthread.h" |
24 | |
25 | int |
26 | pthread_barrier_init(pthread_barrier_t *barrier, pthread_barrierattr_t *attr, |
27 | unsigned int count) { |
28 | int rc = 0; |
29 | pthread_barrier_t b = NULL((void *)0); |
30 | |
31 | if (barrier == NULL((void *)0)) |
32 | return (EINVAL22); |
33 | |
34 | if (count == 0) |
35 | return (EINVAL22); |
36 | |
37 | if (attr != NULL((void *)0)) { |
38 | if (*attr == NULL((void *)0)) |
39 | return (EINVAL22); |
40 | |
41 | if ((*attr)->pshared != PTHREAD_PROCESS_PRIVATE0) |
42 | return (ENOTSUP91); |
43 | } |
44 | |
45 | b = calloc(1, sizeof *b); |
46 | if (b == NULL((void *)0)) |
47 | return (ENOMEM12); |
48 | |
49 | if ((rc = pthread_mutex_init(&b->mutex, NULL((void *)0)))) |
50 | goto err; |
51 | if ((rc = pthread_cond_init(&b->cond, NULL((void *)0)))) |
52 | goto err; |
53 | |
54 | b->threshold = count; |
55 | |
56 | *barrier = b; |
57 | |
58 | return (0); |
59 | |
60 | err: |
61 | if (b) { |
62 | if (b->mutex) |
63 | pthread_mutex_destroy(&b->mutex); |
64 | if (b->cond) |
65 | pthread_cond_destroy(&b->cond); |
66 | free(b); |
67 | } |
68 | |
69 | return (rc); |
70 | } |
71 | |
72 | int |
73 | pthread_barrier_destroy(pthread_barrier_t *barrier) |
74 | { |
75 | int rc; |
76 | pthread_barrier_t b; |
77 | |
78 | if (barrier == NULL((void *)0) || *barrier == NULL((void *)0)) |
79 | return (EINVAL22); |
80 | |
81 | if ((rc = pthread_mutex_lock(&(*barrier)->mutex))) |
82 | return (rc); |
83 | |
84 | b = *barrier; |
85 | |
86 | if (b->out > 0 || b->in > 0) { |
87 | pthread_mutex_unlock(&b->mutex); |
88 | return (EBUSY16); |
89 | } |
90 | |
91 | *barrier = NULL((void *)0); |
92 | pthread_mutex_unlock(&b->mutex); |
93 | pthread_mutex_destroy(&b->mutex); |
94 | pthread_cond_destroy(&b->cond); |
95 | free(b); |
96 | return (0); |
97 | } |
98 | |
99 | int |
100 | pthread_barrier_wait(pthread_barrier_t *barrier) |
101 | { |
102 | pthread_barrier_t b; |
103 | int rc, old_state, gen; |
104 | int done = 0; |
105 | |
106 | if (barrier == NULL((void *)0) || *barrier == NULL((void *)0)) |
107 | return (EINVAL22); |
108 | |
109 | if ((rc = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE1, &old_state))) |
110 | return (rc); |
111 | |
112 | b = *barrier; |
113 | if ((rc = pthread_mutex_lock(&b->mutex))) |
Although the value stored to 'rc' is used in the enclosing expression, the value is never actually read from 'rc' | |
114 | goto cancel; |
115 | |
116 | _rthread_debug(6, "in: %d, threshold: %d\n", b->in, b->threshold); |
117 | if (++b->in == b->threshold) { |
118 | b->out = b->in - 1; |
119 | b->in = 0; |
120 | b->generation++; |
121 | if ((rc = pthread_cond_signal(&b->cond))) |
122 | goto err; |
123 | done = 1; |
124 | _rthread_debug(6, "threshold reached\n"); |
125 | } else { |
126 | gen = b->generation; |
127 | _rthread_debug(6, "waiting on condition\n"); |
128 | do { |
129 | if ((rc = pthread_cond_wait(&b->cond, &b->mutex))) |
130 | goto err; |
131 | } while (gen == b->generation); |
132 | b->out--; /* mark thread exit */ |
133 | if ((rc = pthread_cond_signal(&b->cond))) |
134 | goto err; |
135 | } |
136 | |
137 | err: |
138 | if ((rc = pthread_mutex_unlock(&b->mutex))) |
139 | return (rc); |
140 | cancel: |
141 | rc = pthread_setcancelstate(old_state, NULL((void *)0)); |
142 | if (rc == 0 && done) |
143 | rc = PTHREAD_BARRIER_SERIAL_THREAD-1; |
144 | |
145 | return (rc); |
146 | } |