123b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten/* 223b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten * Copyright (C) 2010 The Android Open Source Project 323b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten * 423b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 523b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten * you may not use this file except in compliance with the License. 623b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten * You may obtain a copy of the License at 723b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten * 823b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 923b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten * 1023b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten * Unless required by applicable law or agreed to in writing, software 1123b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 1223b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1323b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten * See the License for the specific language governing permissions and 1423b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten * limitations under the License. 1523b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten */ 1623b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten 1723b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten/* ThreadSync implementation */ 1823b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten 1923b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten#include "sles_allinclusive.h" 2023b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten 21f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 2223b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kastenstatic SLresult IThreadSync_EnterCriticalSection(SLThreadSyncItf self) 2323b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten{ 24f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SL_ENTER_INTERFACE 25f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 2650bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten IThreadSync *thiz = (IThreadSync *) self; 2750bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_lock_exclusive(thiz); 2823b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten for (;;) { 2950bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten if (thiz->mInCriticalSection) { 3050bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten if (!pthread_equal(thiz->mOwner, pthread_self())) { 3150bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten ++thiz->mWaiting; 3250bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_cond_wait(thiz); 3323b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten continue; 3423b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten } 3515f9f5e609265dff9d6036af38bea084c42a702aGlenn Kasten // nested locks are not allowed 3623b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten result = SL_RESULT_PRECONDITIONS_VIOLATED; 3723b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten break; 3823b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten } 3950bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mInCriticalSection = SL_BOOLEAN_TRUE; 4050bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mOwner = pthread_self(); 4123b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten result = SL_RESULT_SUCCESS; 4223b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten break; 4323b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten } 4450bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_unlock_exclusive(thiz); 45f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 46f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SL_LEAVE_INTERFACE 4723b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten} 4823b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten 49f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 5023b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kastenstatic SLresult IThreadSync_ExitCriticalSection(SLThreadSyncItf self) 5123b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten{ 52f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SL_ENTER_INTERFACE 53f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 5450bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten IThreadSync *thiz = (IThreadSync *) self; 5550bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_lock_exclusive(thiz); 5650bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten if (!thiz->mInCriticalSection || !pthread_equal(thiz->mOwner, pthread_self())) { 5723b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten result = SL_RESULT_PRECONDITIONS_VIOLATED; 5823b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten } else { 5950bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mInCriticalSection = SL_BOOLEAN_FALSE; 6050bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten memset(&thiz->mOwner, 0, sizeof(pthread_t)); 6150bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten if (thiz->mWaiting) { 6250bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten --thiz->mWaiting; 6350bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_cond_signal(thiz); 6423b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten } 65f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten result = SL_RESULT_SUCCESS; 6623b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten } 6750bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten interface_unlock_exclusive(thiz); 68f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 69f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten SL_LEAVE_INTERFACE 7023b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten} 7123b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten 72f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten 7323b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kastenstatic const struct SLThreadSyncItf_ IThreadSync_Itf = { 7423b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten IThreadSync_EnterCriticalSection, 7523b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten IThreadSync_ExitCriticalSection 7623b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten}; 7723b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten 7823b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kastenvoid IThreadSync_init(void *self) 7923b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten{ 8050bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten IThreadSync *thiz = (IThreadSync *) self; 8150bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mItf = &IThreadSync_Itf; 8250bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mInCriticalSection = SL_BOOLEAN_FALSE; 8350bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten thiz->mWaiting = 0; 8450bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten memset(&thiz->mOwner, 0, sizeof(pthread_t)); 8523b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten} 862a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten 872a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kastenvoid IThreadSync_deinit(void *self) 882a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten{ 8950bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten IThreadSync *thiz = (IThreadSync *) self; 9050bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten if (thiz->mInCriticalSection) { 912a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten SL_LOGW("ThreadSync::EnterCriticalSection was active at Engine::Destroy"); 922a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten } 932a25d97e40dbd5dd9195195a3a269095a4932097Glenn Kasten} 94