1 /* 2 * ufdblocks.c - URLfilterDB 3 * 4 * ufdbGuard is copyrighted (C) 2005-2020 by URLfilterDB with all rights reserved. 5 * 6 * Parts of ufdbGuard are based on squidGuard. 7 * This module is NOT based on squidGuard. 8 * 9 * RCS $Id: ufdblocks.c,v 1.6 2020/07/12 07:48:51 root Exp root $ 10 */ 11 12 #ifdef __cplusplus 13 extern "C" { 14 #endif 15 16 /* This module is well tested and stable for a long time. 17 * For maximum performance _FORTIFY_SOURCE is undefined. 18 */ 19 #undef _FORTIFY_SOURCE 20 21 #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) 22 #pragma GCC push_options 23 #pragma GCC optimize ("O3") 24 #endif 25 26 #include "ufdb.h" 27 #include "ufdblocks.h" 28 29 #if UFDB_SPINLOCK_SUPPORT 30 #include <immintrin.h> // defines _mm_pause() 31 #endif 32 33 #if UFDB_PTHREAD_SUPPORT 34 #include <pthread.h> 35 #endif 36 37 #if UFDB_DPDK_SUPPORT 38 #include "rte_spinlock.h" 39 #endif 40 41 #if UFDB_CVMX_SPINLOCK_SUPPORT 42 #include <cvmx-spinlock.h> 43 #endif 44 45 ufdb_mutex_init(ufdb_mutex * m)46void ufdb_mutex_init( ufdb_mutex * m ) 47 { 48 #if UFDB_PTHREAD_SUPPORT 49 pthread_mutex_init( (pthread_mutex_t*) m, NULL ); 50 #elif UFDB_DPDK_SUPPORT 51 rte_spinlock_init( (rte_spinlock_t*) m ); 52 #elif UFDB_SPINLOCK_SUPPORT 53 *m = 0; 54 #elif UFDB_CVMX_SPINLOCK_SUPPORT 55 cvmx_spinlock_init( (cvmx_spinlock_t*) m ); 56 #else 57 *m = 0; 58 #endif 59 } 60 61 ufdb_mutex_lock(ufdb_mutex * m)62int ufdb_mutex_lock( ufdb_mutex * m ) 63 { 64 #if UFDB_PTHREAD_SUPPORT 65 return pthread_mutex_lock( (pthread_mutex_t*) m ); 66 #elif UFDB_DPDK_SUPPORT 67 rte_spinlock_lock( (rte_spinlock_t*) m ); 68 return 0; 69 #elif UFDB_SPINLOCK_SUPPORT 70 int32_t volatile * slp = (int32_t*) m; 71 // spin read-only until a cmpxchg might succeed 72 while(!__sync_bool_compare_and_swap( slp, 0, 1)) 73 { 74 while (*slp) 75 _mm_pause(); // micro-pause to make unlocking easier 76 } 77 return 0; 78 #elif UFDB_CVMX_SPINLOCK_SUPPORT 79 cvmx_spinlock_lock( (cvmx_spinlock_t*) m ); 80 return 0; 81 #else 82 return ENOSYS; // futex not implemented 83 #endif 84 } 85 86 ufdb_mutex_trylock(ufdb_mutex * m)87int ufdb_mutex_trylock( ufdb_mutex * m ) 88 { 89 #if UFDB_PTHREAD_SUPPORT 90 return pthread_mutex_trylock( (pthread_mutex_t*) m ); 91 #elif UFDB_DPDK_SUPPORT 92 int rv = rte_spinlock_trylock( (rte_spinlock_t*) m ); 93 return !rv; 94 #elif UFDB_SPINLOCK_SUPPORT 95 int32_t volatile * slp = (int32_t*) m; 96 int rv = __sync_bool_compare_and_swap( slp, 0, 1 ); 97 return !rv; 98 #elif UFDB_CVMX_SPINLOCK_SUPPORT 99 return cvmx_spinlock_trylock( (cvmx_spinlock_t*) m ); 100 #else 101 return ENOSYS; // futex not implemented 102 #endif 103 } 104 105 ufdb_mutex_unlock(ufdb_mutex * m)106int ufdb_mutex_unlock( ufdb_mutex * m ) 107 { 108 #if UFDB_PTHREAD_SUPPORT 109 return pthread_mutex_unlock( (pthread_mutex_t*) m ); 110 #elif UFDB_DPDK_SUPPORT 111 rte_spinlock_unlock( (rte_spinlock_t*) m ); 112 return 0; 113 #elif UFDB_SPINLOCK_SUPPORT 114 __asm__ volatile("": : :"memory"); // soft memory barrier for the compiler 115 *m = 0; 116 return 0; 117 #elif UFDB_CVMX_SPINLOCK_SUPPORT 118 cvmx_spinlock_unlock( (cvmx_spinlock_t*) m ); 119 return 0; 120 #else 121 return ENOSYS; // futex not implemented 122 #endif 123 } 124 125 126 #ifdef __cplusplus 127 } 128 #endif 129