| File: | src/lib/librthread/rthread_barrier.c |
| Warning: | line 129, column 9 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))) |
| 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))) |
Although the value stored to 'rc' is used in the enclosing expression, the value is never actually read from 'rc' | |
| 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 | } |