locks.c revision a60dbf554549d10780f473b6e1373aa07aec3a28
1a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten/* 2a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * Copyright (C) 2010 The Android Open Source Project 3a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * 4a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 5a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * you may not use this file except in compliance with the License. 6a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * You may obtain a copy of the License at 7a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * 8a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 9a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * 10a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * Unless required by applicable law or agreed to in writing, software 11a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 12a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * See the License for the specific language governing permissions and 14a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * limitations under the License. 15a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten */ 16a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 17a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten#include "sles_allinclusive.h" 18a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 190b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 20928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten/** \brief Exclusively lock an object */ 210b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 22fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#ifdef USE_DEBUG 23bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kastenvoid object_lock_exclusive_(IObject *thiz, const char *file, int line) 24fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten{ 25fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten int ok; 26bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten ok = pthread_mutex_trylock(&thiz->mMutex); 27fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten if (0 != ok) { 284f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten // pthread_mutex_timedlock_np is not available, but wait up to 100 ms 294f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten static const useconds_t backoffs[] = {1, 10000, 20000, 30000, 40000}; 304f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten unsigned i = 0; 314f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten for (;;) { 324f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten usleep(backoffs[i]); 33bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten ok = pthread_mutex_trylock(&thiz->mMutex); 344f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten if (0 == ok) 354f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten break; 364f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten if (++i >= (sizeof(backoffs) / sizeof(backoffs[0]))) { 37b52bc98b576a9b56e82eca435849bd55e54b6bc1Glenn Kasten SL_LOGW("%s:%d: object %p was locked by %p at %s:%d\n", 38bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten file, line, thiz, *(void **)&thiz->mOwner, thiz->mFile, thiz->mLine); 394f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten // attempt one more time; maybe this time we will be successful 40bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten ok = pthread_mutex_lock(&thiz->mMutex); 414f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten assert(0 == ok); 424f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten break; 434f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten } 444f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten } 45fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten } 46fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten pthread_t zero; 47fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten memset(&zero, 0, sizeof(pthread_t)); 48bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (0 != memcmp(&zero, &thiz->mOwner, sizeof(pthread_t))) { 49bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten if (pthread_equal(pthread_self(), thiz->mOwner)) { 504f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten SL_LOGE("%s:%d: object %p was recursively locked by %p at %s:%d\n", 51bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten file, line, thiz, *(void **)&thiz->mOwner, thiz->mFile, thiz->mLine); 524f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten } else { 534f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten SL_LOGE("%s:%d: object %p was left unlocked in unexpected state by %p at %s:%d\n", 54bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten file, line, thiz, *(void **)&thiz->mOwner, thiz->mFile, thiz->mLine); 554f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten } 564f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten assert(false); 574f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten } 58bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mOwner = pthread_self(); 59bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mFile = file; 60bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLine = line; 61fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten} 62fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#else 63bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kastenvoid object_lock_exclusive(IObject *thiz) 64a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{ 65a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten int ok; 66bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten ok = pthread_mutex_lock(&thiz->mMutex); 67a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten assert(0 == ok); 68a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten} 69fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#endif 70a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 710b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 72928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten/** \brief Exclusively unlock an object and do not report any updates */ 730b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 74fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#ifdef USE_DEBUG 75bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kastenvoid object_unlock_exclusive_(IObject *thiz, const char *file, int line) 764597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten{ 77bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten assert(pthread_equal(pthread_self(), thiz->mOwner)); 78bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten assert(NULL != thiz->mFile); 79bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten assert(0 != thiz->mLine); 80bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten memset(&thiz->mOwner, 0, sizeof(pthread_t)); 81bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mFile = file; 82bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLine = line; 83a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten int ok; 84bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten ok = pthread_mutex_unlock(&thiz->mMutex); 85a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten assert(0 == ok); 86a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten} 874597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten#else 88bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kastenvoid object_unlock_exclusive(IObject *thiz) 894597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten{ 904597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten int ok; 91bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten ok = pthread_mutex_unlock(&thiz->mMutex); 924597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten assert(0 == ok); 934597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten} 944597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten#endif 95a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 960b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 97928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten/** \brief Exclusively unlock an object and report updates to the specified bit-mask of 98928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten * attributes 99928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten */ 1000b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 1014597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten#ifdef USE_DEBUG 102bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kastenvoid object_unlock_exclusive_attributes_(IObject *thiz, unsigned attributes, 1034597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten const char *file, int line) 1044597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten#else 105bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kastenvoid object_unlock_exclusive_attributes(IObject *thiz, unsigned attributes) 1064597a7427b697df31d0bbf4c2040806d0c27b6e0Glenn Kasten#endif 107e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten{ 108fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten 109fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#ifdef USE_DEBUG 110bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten assert(pthread_equal(pthread_self(), thiz->mOwner)); 111bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten assert(NULL != thiz->mFile); 112bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten assert(0 != thiz->mLine); 113fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#endif 114fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten 115e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten int ok; 1163c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi 1177b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten // make SL object IDs be contiguous with XA object IDs 1187b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten SLuint32 objectID = IObjectToObjectID(thiz); 11947550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten SLuint32 index = objectID; 12047550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten if ((XA_OBJECTID_ENGINE <= index) && (index <= XA_OBJECTID_CAMERADEVICE)) { 1217b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten ; 12247550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten } else if ((SL_OBJECTID_ENGINE <= index) && (index <= SL_OBJECTID_METADATAEXTRACTOR)) { 12347550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten index -= SL_OBJECTID_ENGINE - XA_OBJECTID_CAMERADEVICE - 1; 1247b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten } else { 1257b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten assert(false); 12647550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten index = 0; 1273c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi } 1283c170255cc71942f310b676d968cf73328aa5d70Jean-Michel Trivi 1297b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten // first synchronously handle updates to attributes here, while object is still locked. 1307b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten // This appears to be a loop, but actually typically runs through the loop only once. 1317b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten unsigned asynchronous = attributes; 1327b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten while (attributes) { 1337b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten // this sequence is carefully crafted to be O(1); tread carefully when making changes 1347b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten unsigned bit = ctz(attributes); 1357b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten // ATTR_INDEX_MAX == next bit position after the last attribute 1367b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten assert(ATTR_INDEX_MAX > bit); 1377b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten // compute the entry in the handler table using object ID and bit number 13847550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten AttributeHandler handler = handlerTable[index][bit]; 1397b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten if (NULL != handler) { 1407b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten asynchronous &= ~(*handler)(thiz); 141e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten } 1427b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten attributes &= ~(1 << bit); 143e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten } 1444b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 1457b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten // any remaining attributes are handled asynchronously in the sync thread 1467b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten if (asynchronous) { 1477b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten unsigned oldAttributesMask = thiz->mAttributesMask; 1487b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten thiz->mAttributesMask = oldAttributesMask | asynchronous; 1497b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten if (oldAttributesMask) { 1507b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten asynchronous = ATTR_NONE; 151d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi } 152d158d31a6bbb06426b71c3d097b7768bc3fb79a3Jean-Michel Trivi } 1534b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten 15447550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten#ifdef ANDROID 155a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten // FIXME hack to safely handle a post-unlock PrefetchStatus callback and/or AudioTrack::start() 156a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten slPrefetchCallback prefetchCallback = NULL; 157a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten void *prefetchContext = NULL; 158a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten SLuint32 prefetchEvents = SL_PREFETCHEVENT_NONE; 15947550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten android::sp<android::AudioTrackProxy> audioTrack; 16047550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten if (SL_OBJECTID_AUDIOPLAYER == objectID) { 16147550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten CAudioPlayer *ap = (CAudioPlayer *) thiz; 162a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten prefetchCallback = ap->mPrefetchStatus.mDeferredPrefetchCallback; 163a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten prefetchContext = ap->mPrefetchStatus.mDeferredPrefetchContext; 164a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten prefetchEvents = ap->mPrefetchStatus.mDeferredPrefetchEvents; 165a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten ap->mPrefetchStatus.mDeferredPrefetchCallback = NULL; 166a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten // clearing these next two fields is not required, but avoids stale data during debugging 167a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten ap->mPrefetchStatus.mDeferredPrefetchContext = NULL; 168a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten ap->mPrefetchStatus.mDeferredPrefetchEvents = SL_PREFETCHEVENT_NONE; 16947550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten if (ap->mDeferredStart) { 17047550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten audioTrack = ap->mAudioTrack; 17147550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten ap->mDeferredStart = false; 17247550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten } 17347550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten } 17447550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten#endif 17547550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten 176fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#ifdef USE_DEBUG 177bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten memset(&thiz->mOwner, 0, sizeof(pthread_t)); 178bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mFile = file; 179bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLine = line; 180fe96fa06360516c60490c7a697e1148017b4c1b2Glenn Kasten#endif 181bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten ok = pthread_mutex_unlock(&thiz->mMutex); 182e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten assert(0 == ok); 1837b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten 18447550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten#ifdef ANDROID 185a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten // FIXME call the prefetch status callback while not holding the mutex on AudioPlayer 186a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten if (NULL != prefetchCallback) { 187a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten // note these are synchronous by the application's thread as it is about to return from API 188a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten assert(prefetchEvents != SL_PREFETCHEVENT_NONE); 189a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten CAudioPlayer *ap = (CAudioPlayer *) thiz; 190a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten // spec requires separate callbacks for each event 191a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten if (SL_PREFETCHEVENT_STATUSCHANGE & prefetchEvents) { 192a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten (*prefetchCallback)(&ap->mPrefetchStatus.mItf, prefetchContext, 193a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten SL_PREFETCHEVENT_STATUSCHANGE); 194a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten } 195a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten if (SL_PREFETCHEVENT_FILLLEVELCHANGE & prefetchEvents) { 196a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten (*prefetchCallback)(&ap->mPrefetchStatus.mItf, prefetchContext, 197a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten SL_PREFETCHEVENT_FILLLEVELCHANGE); 198a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten } 199a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten } 200a60dbf554549d10780f473b6e1373aa07aec3a28Glenn Kasten 20147550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten // call AudioTrack::start() while not holding the mutex on AudioPlayer 20247550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten if (audioTrack != 0) { 20347550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten audioTrack->start(); 20447550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten audioTrack.clear(); 20547550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten } 20647550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten#endif 20747550bf6cf5cf08a402a54b1589f4b64582a5120Glenn Kasten 208f51dba65751107c930759938775b75531ec1f330Glenn Kasten // first update to this interface since previous sync 2097b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten if (ATTR_NONE != asynchronous) { 210bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten unsigned id = thiz->mInstanceID; 211f51dba65751107c930759938775b75531ec1f330Glenn Kasten if (0 != id) { 212f51dba65751107c930759938775b75531ec1f330Glenn Kasten --id; 213f51dba65751107c930759938775b75531ec1f330Glenn Kasten assert(MAX_INSTANCE > id); 214bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten IEngine *thisEngine = &thiz->mEngine->mEngine; 2157b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten // FIXME atomic or here 216f51dba65751107c930759938775b75531ec1f330Glenn Kasten interface_lock_exclusive(thisEngine); 217f51dba65751107c930759938775b75531ec1f330Glenn Kasten thisEngine->mChangedMask |= 1 << id; 218f51dba65751107c930759938775b75531ec1f330Glenn Kasten interface_unlock_exclusive(thisEngine); 219f51dba65751107c930759938775b75531ec1f330Glenn Kasten } 220e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten } 2217b726bdcd996f1cab3a584c04ce1afc07bc8fbe7Glenn Kasten 222e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten} 223e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten 2240b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 225928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten/** \brief Wait on the condition variable associated with the object; see pthread_cond_wait */ 2260b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 2274f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten#ifdef USE_DEBUG 228bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kastenvoid object_cond_wait_(IObject *thiz, const char *file, int line) 2294f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten{ 2304f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten // note that this will unlock the mutex, so we have to clear the owner 231bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten assert(pthread_equal(pthread_self(), thiz->mOwner)); 232bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten assert(NULL != thiz->mFile); 233bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten assert(0 != thiz->mLine); 234bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten memset(&thiz->mOwner, 0, sizeof(pthread_t)); 235bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mFile = file; 236bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLine = line; 2374f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten // alas we don't know the new owner's identity 2384f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten int ok; 239bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten ok = pthread_cond_wait(&thiz->mCond, &thiz->mMutex); 2404f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten assert(0 == ok); 2414f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten // restore my ownership 242bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mOwner = pthread_self(); 243bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mFile = file; 244bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten thiz->mLine = line; 2454f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten} 2464f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten#else 247bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kastenvoid object_cond_wait(IObject *thiz) 248a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{ 249a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten int ok; 250bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten ok = pthread_cond_wait(&thiz->mCond, &thiz->mMutex); 251a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten assert(0 == ok); 252a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten} 2534f064c143ef2b26347130a49788116b5d2e1252aGlenn Kasten#endif 254a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten 2550b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 256928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten/** \brief Signal the condition variable associated with the object; see pthread_cond_signal */ 2570b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 258bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kastenvoid object_cond_signal(IObject *thiz) 259a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{ 260a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten int ok; 261bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten ok = pthread_cond_signal(&thiz->mCond); 262a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten assert(0 == ok); 263a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten} 264a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten 2650b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 266928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten/** \brief Broadcast the condition variable associated with the object; 267928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten * see pthread_cond_broadcast 268928ea4ffff40c82987cfb1ac9e3095fdc6968709Glenn Kasten */ 2690b595cc18d82e41dfab0c686e9e63c30a86e8c80Glenn Kasten 270bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kastenvoid object_cond_broadcast(IObject *thiz) 271a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten{ 272a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten int ok; 273bcc5c7225e3b7a1dbf2e9e830987f69167acf06fGlenn Kasten ok = pthread_cond_broadcast(&thiz->mCond); 274a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten assert(0 == ok); 275a438eb1cf1ae602afab00336528dd230bd929206Glenn Kasten} 276