1/* 2 * Copyright (c) 2008-2013 Apple Inc. All rights reserved. 3 * 4 * @APPLE_APACHE_LICENSE_HEADER_START@ 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 * @APPLE_APACHE_LICENSE_HEADER_END@ 19 */ 20 21/* 22 * IMPORTANT: This header file describes INTERNAL interfaces to libdispatch 23 * which are subject to change in future releases of Mac OS X. Any applications 24 * relying on these interfaces WILL break. 25 */ 26 27#ifndef __DISPATCH_SHIMS_PERFMON__ 28#define __DISPATCH_SHIMS_PERFMON__ 29 30#if DISPATCH_PERF_MON 31 32#if defined (USE_APPLE_TSD_OPTIMIZATIONS) && defined(SIMULATE_5491082) && \ 33 (defined(__i386__) || defined(__x86_64__)) 34#ifdef __LP64__ 35#define _dispatch_perfmon_workitem_inc() asm("incq %%gs:%0" : "+m" \ 36 (*(void **)(dispatch_bcounter_key * sizeof(void *) + \ 37 _PTHREAD_TSD_OFFSET)) :: "cc") 38#define _dispatch_perfmon_workitem_dec() asm("decq %%gs:%0" : "+m" \ 39 (*(void **)(dispatch_bcounter_key * sizeof(void *) + \ 40 _PTHREAD_TSD_OFFSET)) :: "cc") 41#else 42#define _dispatch_perfmon_workitem_inc() asm("incl %%gs:%0" : "+m" \ 43 (*(void **)(dispatch_bcounter_key * sizeof(void *) + \ 44 _PTHREAD_TSD_OFFSET)) :: "cc") 45#define _dispatch_perfmon_workitem_dec() asm("decl %%gs:%0" : "+m" \ 46 (*(void **)(dispatch_bcounter_key * sizeof(void *) + \ 47 _PTHREAD_TSD_OFFSET)) :: "cc") 48#endif 49#else /* !USE_APPLE_TSD_OPTIMIZATIONS */ 50static inline void 51_dispatch_perfmon_workitem_inc(void) 52{ 53 unsigned long cnt; 54 cnt = (unsigned long)_dispatch_thread_getspecific(dispatch_bcounter_key); 55 _dispatch_thread_setspecific(dispatch_bcounter_key, (void *)++cnt); 56} 57static inline void 58_dispatch_perfmon_workitem_dec(void) 59{ 60 unsigned long cnt; 61 cnt = (unsigned long)_dispatch_thread_getspecific(dispatch_bcounter_key); 62 _dispatch_thread_setspecific(dispatch_bcounter_key, (void *)--cnt); 63} 64#endif /* USE_APPLE_TSD_OPTIMIZATIONS */ 65 66// C99 doesn't define flsll() or ffsll() 67#ifdef __LP64__ 68#define flsll(x) flsl(x) 69#else 70static inline unsigned int 71flsll(uint64_t val) 72{ 73 union { 74 struct { 75#ifdef __BIG_ENDIAN__ 76 unsigned int hi, low; 77#else 78 unsigned int low, hi; 79#endif 80 } words; 81 uint64_t word; 82 } _bucket = { 83 .word = val, 84 }; 85 if (_bucket.words.hi) { 86 return fls(_bucket.words.hi) + 32; 87 } 88 return fls(_bucket.words.low); 89} 90#endif 91 92#define _dispatch_perfmon_start() \ 93 uint64_t start = _dispatch_absolute_time() 94#define _dispatch_perfmon_end() \ 95 _dispatch_queue_merge_stats(start) 96#else 97 98#define _dispatch_perfmon_workitem_inc() 99#define _dispatch_perfmon_workitem_dec() 100#define _dispatch_perfmon_start() 101#define _dispatch_perfmon_end() 102 103#endif // DISPATCH_PERF_MON 104 105#endif 106