multithread.c revision 0a058cc3d720cdf3f0f8222472a862258482f34f
17126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten/* 27126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten * Copyright (C) 2010 The Android Open Source Project 37126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten * 47126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 57126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten * you may not use this file except in compliance with the License. 67126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten * You may obtain a copy of the License at 77126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten * 87126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 97126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten * 107126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten * Unless required by applicable law or agreed to in writing, software 117126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 127126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten * See the License for the specific language governing permissions and 147126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten * limitations under the License. 157126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten */ 167126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 177126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten// Multiple threads create and destroy objects 187126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 197126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten#include "SLES/OpenSLES.h" 207126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten#include <assert.h> 217126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten#include <pthread.h> 227126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten//#include <string.h> 237126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten#include <stdio.h> 247126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten#include <stdlib.h> 257126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten#include <unistd.h> 260a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten#include <utils/Log.h> 277126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 287126c25d7c037e5086216cf540ecf40779c3585aGlenn Kastentypedef struct { 297126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten SLuint32 mObjectID; 307126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten SLchar *mURI; 317126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten SLEngineItf mEngineEngine; 327126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten SLObjectItf mMixObject; 337126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten SLuint32 mCounter; 347126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten} ThreadArgument; 357126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 367126c25d7c037e5086216cf540ecf40779c3585aGlenn Kastenvolatile int timeToExit = 0; 377126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten#define MAX_THREAD 10 387126c25d7c037e5086216cf540ecf40779c3585aGlenn Kastenpthread_t threads[MAX_THREAD]; 397126c25d7c037e5086216cf540ecf40779c3585aGlenn KastenThreadArgument thread_args[MAX_THREAD]; 407126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 417126c25d7c037e5086216cf540ecf40779c3585aGlenn Kastenpthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 427126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 437126c25d7c037e5086216cf540ecf40779c3585aGlenn Kastenvoid *thread_start(void *param) 447126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten{ 457126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten //pthread_mutex_lock(&mutex); 467126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten //pthread_mutex_unlock(&mutex); 477126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten ThreadArgument *ta = (ThreadArgument *) param; 487126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 497126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten while (!timeToExit) { 507126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten SLresult result; 517126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 527126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten ++ta->mCounter; 530a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten //LOGE("mCounter %d", ta->mCounter); 547126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten switch (ta->mObjectID) { 557126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten case SL_OBJECTID_OUTPUTMIX: 567126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten { 577126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten SLObjectItf myMixObject; 587126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten result = (*ta->mEngineEngine)->CreateOutputMix(ta->mEngineEngine, &myMixObject, 0, NULL, 597126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten NULL); 607126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten assert(SL_RESULT_SUCCESS == result); 617126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten result = (*myMixObject)->Realize(myMixObject, SL_BOOLEAN_FALSE); 627126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten assert(SL_RESULT_SUCCESS == result); 637126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten (*myMixObject)->Destroy(myMixObject); 647126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten } 657126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten break; 667126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 677126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten case SL_OBJECTID_AUDIOPLAYER: 687126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten { 697126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten SLDataLocator_URI locURI = {SL_DATALOCATOR_URI, ta->mURI}; 707126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten SLDataFormat_MIME dfMIME = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED}; 717126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten SLDataSource audioSrc = {&locURI, &dfMIME}; 727126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten SLDataLocator_OutputMix locOutputMix = {SL_DATALOCATOR_OUTPUTMIX, ta->mMixObject}; 737126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten SLDataSink audioSnk = {&locOutputMix, NULL}; 747126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten SLObjectItf myPlayerObject; 757126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten result = (*ta->mEngineEngine)->CreateAudioPlayer(ta->mEngineEngine, &myPlayerObject, 767126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten &audioSrc, &audioSnk, 0, NULL, NULL); 777126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten assert(SL_RESULT_SUCCESS == result); 787126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten result = (*myPlayerObject)->Realize(myPlayerObject, SL_BOOLEAN_FALSE); 797126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten assert(SL_RESULT_SUCCESS == result); 807126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten SLPlayItf playerPlay; 817126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten result = (*myPlayerObject)->GetInterface(myPlayerObject, SL_IID_PLAY, &playerPlay); 827126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten assert(SL_RESULT_SUCCESS == result); 830a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PAUSED); 847126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten assert(SL_RESULT_SUCCESS == result); 850a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten usleep(1000 + (rand() & 0xFFF)); 860a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten //usleep(1000); 870a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten //sleep(1); 887126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten (*myPlayerObject)->Destroy(myPlayerObject); 897126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten } 907126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten break; 917126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 927126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten default: 937126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten break; 947126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 957126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten } 967126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten //usleep(100000); 970a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten //break; 987126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten } 997126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 1007126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten return NULL; 1017126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten} 1027126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 1037126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 1040a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten//const char * const uris[4] = {"wav/frog.wav", "wav/bach.wav", "wav/8days.wav", "wav/help16.wav"}; 1050a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kastenconst char * const uris[4] = {"wav/frog.wav", "wav/frog.wav", "wav/frog.wav", "wav/frog.wav"}; 1067126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 1077126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten// Main program 1087126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 1097126c25d7c037e5086216cf540ecf40779c3585aGlenn Kastenint main(int argc, char **argv) 1107126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten{ 1117126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten SLresult result; 1127126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 1137126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten // create engine 1147126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten SLObjectItf engineObject; 1157126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); 1167126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten assert(SL_RESULT_SUCCESS == result); 1177126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); 1187126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten assert(SL_RESULT_SUCCESS == result); 1197126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten SLEngineItf engineEngine; 1207126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); 1217126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten assert(SL_RESULT_SUCCESS == result); 1227126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 1237126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten // create output mix 1247126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten SLObjectItf mixObject; 1257126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten result = (*engineEngine)->CreateOutputMix(engineEngine, &mixObject, 0, NULL, NULL); 1267126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten assert(SL_RESULT_SUCCESS == result); 1277126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten result = (*mixObject)->Realize(mixObject, SL_BOOLEAN_FALSE); 1287126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten assert(SL_RESULT_SUCCESS == result); 1297126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 1307126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten // create threads 1317126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten int i; 1327126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten int ok; 1337126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten for (i = 0; i < MAX_THREAD; ++i) { 1347126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten ThreadArgument *ta = &thread_args[i]; 1357126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten int r = rand(); 1367126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten switch (r & 1) { 1377126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten#if 0 1387126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten case 0: 1397126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten ta->mObjectID = SL_OBJECTID_OUTPUTMIX; 1407126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten ta->mURI = NULL; 1417126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten ta->mEngineEngine = engineEngine; 1427126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten ta->mMixObject = NULL; 1437126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten ta->mCounter = 0; 1447126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten break; 1457126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten case 1: 1467126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten#endif 1477126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten default: 1487126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten ta->mObjectID = SL_OBJECTID_AUDIOPLAYER; 1497126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten ta->mURI = (SLchar *) uris[(r >> 1) & 3]; 1507126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten ta->mEngineEngine = engineEngine; 1517126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten ta->mMixObject = mixObject; 1527126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten ta->mCounter = 0; 1537126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten break; 1547126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten } 1557126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten //pthread_mutex_lock(&mutex); 1567126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten //pthread_mutex_unlock(&mutex); 1577126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten ok = pthread_create(&threads[i], (const pthread_attr_t *) NULL, thread_start, 1587126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten &thread_args[i]); 1597126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten assert(0 == ok); 1607126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten } 1617126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 1627126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten // let it run for a while 1637126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten int j; 1640a058cc3d720cdf3f0f8222472a862258482f34fGlenn Kasten for (j = 0; j < 100; ++j) { 1657126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten sleep(1); 1667126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten for (i = 0; i < MAX_THREAD; ++i) { 1677126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten ThreadArgument *ta = &thread_args[i]; 1687126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten printf("[%d]=%lu ", j, ta->mCounter); 1697126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten } 1707126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten printf("\n"); 1717126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten } 1727126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 1737126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten // signal threads that they should exit 1747126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten timeToExit = 1; 1757126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 1767126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten for (j = 0; j < 3; ++j) { 1777126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten sleep(1); 1787126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten for (i = 0; i < MAX_THREAD; ++i) { 1797126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten ThreadArgument *ta = &thread_args[i]; 1807126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten printf("[%d]=%lu ", j, ta->mCounter); 1817126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten } 1827126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten printf("\n"); 1837126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten } 1847126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 1857126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten // now wait for the threads to actually exit 1867126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten for (i = 0; i < MAX_THREAD; ++i) { 1877126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten ok = pthread_join(threads[i], NULL); 1887126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten assert(0 == ok); 1897126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten } 1907126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 1917126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten // tear down objects 1927126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten (*mixObject)->Destroy(mixObject); 1937126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten (*engineObject)->Destroy(engineObject); 1947126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten 1957126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten return EXIT_SUCCESS; 1967126c25d7c037e5086216cf540ecf40779c3585aGlenn Kasten} 197