Line data Source code
1 : /* 2 : * lwan - web server 3 : * Copyright (c) 2018 L. A. F. Pereira <l@tia.mat.br> 4 : * 5 : * This program is free software; you can redistribute it and/or 6 : * modify it under the terms of the GNU General Public License 7 : * as published by the Free Software Foundation; either version 2 8 : * of the License, or any later version. 9 : * 10 : * This program is distributed in the hope that it will be useful, 11 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 : * GNU General Public License for more details. 14 : * 15 : * You should have received a copy of the GNU General Public License 16 : * along with this program; if not, write to the Free Software 17 : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 : */ 19 : 20 : #define _GNU_SOURCE 21 : #include <errno.h> 22 : #include <string.h> 23 : #include <pthread.h> 24 : 25 : #ifdef __FreeBSD__ 26 : #include <pthread_np.h> 27 : #endif 28 : 29 : #include "lwan-private.h" 30 : 31 : #ifndef LWAN_HAVE_PTHREADBARRIER 32 : #define PTHREAD_BARRIER_SERIAL_THREAD -1 33 : 34 : int 35 : pthread_barrier_init(pthread_barrier_t *restrict barrier, 36 : const pthread_barrierattr_t *restrict attr __attribute__((unused)), 37 : unsigned int count) { 38 : if (count == 0) { 39 : return -1; 40 : } 41 : 42 : barrier->count = count; 43 : barrier->in = 0; 44 : 45 : if (pthread_mutex_init(&barrier->mutex, NULL) < 0) 46 : return -1; 47 : 48 : if (pthread_cond_init(&barrier->cond, NULL) < 0) { 49 : pthread_mutex_destroy(&barrier->mutex); 50 : return -1; 51 : } 52 : 53 : return 0; 54 : } 55 : 56 : int 57 : pthread_barrier_destroy(pthread_barrier_t *barrier) 58 : { 59 : pthread_mutex_destroy(&barrier->mutex); 60 : pthread_cond_destroy(&barrier->cond); 61 : barrier->in = 0; 62 : 63 : return 0; 64 : } 65 : 66 : int 67 : pthread_barrier_wait(pthread_barrier_t *barrier) 68 : { 69 : pthread_mutex_lock(&barrier->mutex); 70 : 71 : barrier->in++; 72 : if (barrier->in >= barrier->count) { 73 : barrier->in = 0; 74 : pthread_cond_broadcast(&barrier->cond); 75 : pthread_mutex_unlock(&barrier->mutex); 76 : 77 : return PTHREAD_BARRIER_SERIAL_THREAD; 78 : } 79 : 80 : pthread_cond_wait(&barrier->cond, &barrier->mutex); 81 : pthread_mutex_unlock(&barrier->mutex); 82 : 83 : return 0; 84 : } 85 : #endif 86 : 87 : #if defined(__linux__) 88 368 : int pthread_set_name_np(pthread_t thread, const char *name) 89 : { 90 368 : return pthread_setname_np(thread, name); 91 : } 92 : #elif defined(__APPLE__) 93 : int pthread_set_name_np(pthread_t thread, const char *name) 94 : { 95 : if (!pthread_equal(thread, pthread_self())) 96 : return EPERM; 97 : 98 : /* macOS takes a char*; I don't know if it's modified or not, so 99 : * copy it on the stack. */ 100 : return pthread_setname_np(strdupa(name)); 101 : } 102 : #endif