1 /* 2 cs_par_base.h: 3 4 Copyright (C) 2011, 2017 John ffitch and Stephen Kyne 5 6 This file is part of Csound. 7 8 The Csound Library is free software; you can redistribute it 9 and/or modify it under the terms of the GNU Lesser General Public 10 License as published by the Free Software Foundation; either 11 version 2.1 of the License, or (at your option) any later version. 12 13 Csound is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU Lesser General Public License for more details. 17 18 You should have received a copy of the GNU Lesser General Public 19 License along with Csound; if not, write to the Free Software 20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 02110-1301 USA 22 */ 23 24 #ifndef __CS_PAR_BASE_H__ 25 #define __CS_PAR_BASE_H__ 26 27 // Semaphone.h only exists when using pthreads, doesn't apply to Windows 28 #ifndef WIN32 29 #include <semaphore.h> 30 #endif 31 32 /* #define TAKE_LOCK(x) pthread_spin_lock(x) 33 #define RELS_LOCK(x) pthread_spin_unlock(x) 34 #define LOCK_TYPE pthread_spinlock_t 35 #define INIT_LOCK(x) pthread_spin_init(&(x), PTHREAD_PROCESS_PRIVATE)*/ 36 37 /* #define TAKE_LOCK(x) pthread_mutex_lock(x) */ 38 /* #define RELS_LOCK(x) pthread_mutex_unlock(x) */ 39 /* #define LOCK_TYPE pthread_mutex_t */ 40 /* #define INIT_LOCK(x) pthread_mutex_init(&(x), NULL) */ 41 42 #if !defined(HAVE_PTHREAD_SPIN_LOCK) 43 // Windows environment should use native threads 44 # if WIN32 45 #define TAKE_LOCK(x) csoundLockMutex(x) 46 #define RELS_LOCK(x) csoundUnlockMutex(x) 47 #define LOCK_TYPE LPCRITICAL_SECTION 48 // PTHREAD: FIXME no init function? unless createMutex should be used 49 // but has a different function signature 50 #define INIT_LOCK(x) csoundCreateMutex(0) 51 # else 52 /* VL: 18.05.2011 enabled this to allow OSX build */ 53 #define TAKE_LOCK(x) pthread_mutex_lock(x) 54 #define RELS_LOCK(x) pthread_mutex_unlock(x) 55 #define LOCK_TYPE pthread_mutex_t 56 #define INIT_LOCK(x) pthread_mutex_init(&(x), NULL) 57 # endif 58 #else 59 #define TAKE_LOCK(x) pthread_spin_lock(x) 60 #define RELS_LOCK(x) pthread_spin_unlock(x) 61 #define LOCK_TYPE pthread_spinlock_t 62 #define INIT_LOCK(x) pthread_spin_init(&(x), PTHREAD_PROCESS_PRIVATE) 63 #endif 64 65 #define DYNAMIC_2_SERIALIZE_PAR 66 67 /* #define TIMING */ 68 69 /* #define SPINLOCK_BARRIER */ 70 /* #define SPINLOCK_2_BARRIER */ 71 72 #define HASH_CACHE 73 /* #define HYBRID_HASH_CACHE */ 74 /* #define LINEAR_CACHE */ 75 76 /* #define CACLULATE_WEIGHTS_BUILD */ 77 #define LOOKUP_WEIGHTS 78 79 #define KPERF_SYM 0x31 80 #define BARRIER_1_WAIT_SYM 0x32 81 #define BARRIER_2_WAIT_SYM 0x33 82 83 /* return thread index of caller */ 84 int csp_thread_index_get(CSOUND *csound); 85 86 /* structure headers */ 87 #define HDR_LEN 4 88 //#define INSTR_WEIGHT_INFO_HDR "IWI" 89 #define INSTR_SEMANTICS_HDR "SEM" 90 #define SET_ELEMENT_HDR "STE" 91 #define SET_HDR "SET" 92 //#define DAG_2_HDR "DG2" 93 //#define DAG_NODE_2_HDR "DN2" 94 //#define SEMAPHORE_HDR "SPS" 95 #define GLOBAL_VAR_LOCK_HDR "GVL" 96 //#define SERIALIZED_DAG_HDR "SDG" 97 98 /* 99 * set structures 100 * 101 * set maintains insertion order of elements 102 * implemented as a singly linked list 103 */ 104 struct set_element_t { 105 char hdr[4]; 106 void *data; 107 struct set_element_t *next; 108 }; 109 110 struct set_t { 111 char hdr[4]; 112 struct set_element_t *head; 113 struct set_element_t *tail; 114 int count; 115 int (*ele_eq_func)(struct set_element_t *, struct set_element_t *); 116 void (*ele_print_func)(CSOUND *, struct set_element_t *); 117 struct set_element_t **cache; 118 }; 119 120 /* function pointer types for set member equality */ 121 typedef int (set_element_data_eq)(struct set_element_t *, struct set_element_t *); 122 int csp_set_element_string_eq(struct set_element_t *ele1, 123 struct set_element_t *ele2); 124 int csp_set_element_ptr_eq(struct set_element_t *ele1, 125 struct set_element_t *ele2); 126 127 /* function pointer types for set member printing */ 128 typedef void (set_element_data_print)(CSOUND *, struct set_element_t *); 129 void csp_set_element_string_print(CSOUND *csound, struct set_element_t *ele); 130 void csp_set_element_ptr_print(CSOUND *csound, struct set_element_t *ele); 131 132 /* allocating sets with specification of element equality and printing functions */ 133 struct set_t *csp_set_alloc(CSOUND *csound, 134 set_element_data_eq *ele_eq_func, 135 set_element_data_print *ele_print_func); 136 void csp_set_dealloc(CSOUND *csound, struct set_t **set); 137 /* shortcut to get a set of strings uses string element equality and 138 printing functions */ 139 struct set_t *csp_set_alloc_string(CSOUND *csound); 140 141 /* functions to manipulate set, return CSOUND_SUCCESS if successful */ 142 void csp_set_add(CSOUND *csound, struct set_t *set, void *data); 143 void csp_set_remove(CSOUND *csound, struct set_t *set, void *data); 144 /* check element existance returns 1 if data exists */ 145 void csp_set_print(CSOUND *csound, struct set_t *set); 146 147 /* get a count and access members */ 148 int csp_set_count(struct set_t *set); 149 150 /* 151 * set union and intersection 152 * allocates a new set in result 153 * union/intersect first and second putting into result 154 */ 155 struct set_t *csp_set_union(CSOUND *csound, struct set_t *first, 156 struct set_t *second); 157 struct set_t *csp_set_intersection(CSOUND *csound, struct set_t *first, 158 struct set_t *second); 159 160 /* spinlock */ 161 162 /* semaphore */ 163 /* struct semaphore_spin_t { */ 164 /* char hdr[HDR_LEN]; */ 165 /* int thread_count; */ 166 /* int max_threads; */ 167 /* int arrived; */ 168 /* int held; */ 169 /* int spinlock; */ 170 /* int count; */ 171 /* int lock; */ 172 /* int *key; */ 173 /* int locks[]; */ 174 /* }; */ 175 176 // Kludge to allow us to pass in HANDLE objects to be used as semaphore whilst 177 // supporting the traditional pthread way for non Windows platforms 178 // FIXME, does this even work? API's take ** versions of sem_t 179 #ifdef WIN32 180 typedef HANDLE sem_t; 181 #endif 182 183 /* create a semaphore with a maximum number of threads 184 * initially 1 thread is allowed in 185 */ 186 void csp_semaphore_alloc(CSOUND *csound, sem_t **sem, 187 int max_threads); 188 void csp_semaphore_dealloc(CSOUND *csound, sem_t **sem); 189 /* wait at the semaphore. if the number allowed in is greater than the 190 * number arrived calling thread continues 191 * otherwise thread blocks until semaphore is grown 192 */ 193 void csp_semaphore_wait(CSOUND *csound, sem_t *sem); 194 /* increase the number of threads allowed in by 1 */ 195 void csp_semaphore_grow(CSOUND *csound, sem_t *sem); 196 /* reduce the number of threads allowed in and the arrive count by 1 197 * call this when calling thread is finished with the semaphore. */ 198 void csp_semaphore_release(CSOUND *csound, sem_t *sem); 199 /* call when all threads are done with the resource the semaphore is protecting. 200 * releases all blocked threads. */ 201 void csp_semaphore_release_end(CSOUND *csound, sem_t *sem); 202 /* print semaphore info */ 203 void csp_semaphore_release_print(CSOUND *csound, sem_t *sem); 204 205 #endif /* end of include guard: __CS_PAR_BASE_H__ */ 206