multithread.c revision 0a058cc3d720cdf3f0f8222472a862258482f34f
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17// Multiple threads create and destroy objects 18 19#include "SLES/OpenSLES.h" 20#include <assert.h> 21#include <pthread.h> 22//#include <string.h> 23#include <stdio.h> 24#include <stdlib.h> 25#include <unistd.h> 26#include <utils/Log.h> 27 28typedef struct { 29 SLuint32 mObjectID; 30 SLchar *mURI; 31 SLEngineItf mEngineEngine; 32 SLObjectItf mMixObject; 33 SLuint32 mCounter; 34} ThreadArgument; 35 36volatile int timeToExit = 0; 37#define MAX_THREAD 10 38pthread_t threads[MAX_THREAD]; 39ThreadArgument thread_args[MAX_THREAD]; 40 41pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 42 43void *thread_start(void *param) 44{ 45 //pthread_mutex_lock(&mutex); 46 //pthread_mutex_unlock(&mutex); 47 ThreadArgument *ta = (ThreadArgument *) param; 48 49 while (!timeToExit) { 50 SLresult result; 51 52 ++ta->mCounter; 53 //LOGE("mCounter %d", ta->mCounter); 54 switch (ta->mObjectID) { 55 case SL_OBJECTID_OUTPUTMIX: 56 { 57 SLObjectItf myMixObject; 58 result = (*ta->mEngineEngine)->CreateOutputMix(ta->mEngineEngine, &myMixObject, 0, NULL, 59 NULL); 60 assert(SL_RESULT_SUCCESS == result); 61 result = (*myMixObject)->Realize(myMixObject, SL_BOOLEAN_FALSE); 62 assert(SL_RESULT_SUCCESS == result); 63 (*myMixObject)->Destroy(myMixObject); 64 } 65 break; 66 67 case SL_OBJECTID_AUDIOPLAYER: 68 { 69 SLDataLocator_URI locURI = {SL_DATALOCATOR_URI, ta->mURI}; 70 SLDataFormat_MIME dfMIME = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED}; 71 SLDataSource audioSrc = {&locURI, &dfMIME}; 72 SLDataLocator_OutputMix locOutputMix = {SL_DATALOCATOR_OUTPUTMIX, ta->mMixObject}; 73 SLDataSink audioSnk = {&locOutputMix, NULL}; 74 SLObjectItf myPlayerObject; 75 result = (*ta->mEngineEngine)->CreateAudioPlayer(ta->mEngineEngine, &myPlayerObject, 76 &audioSrc, &audioSnk, 0, NULL, NULL); 77 assert(SL_RESULT_SUCCESS == result); 78 result = (*myPlayerObject)->Realize(myPlayerObject, SL_BOOLEAN_FALSE); 79 assert(SL_RESULT_SUCCESS == result); 80 SLPlayItf playerPlay; 81 result = (*myPlayerObject)->GetInterface(myPlayerObject, SL_IID_PLAY, &playerPlay); 82 assert(SL_RESULT_SUCCESS == result); 83 result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PAUSED); 84 assert(SL_RESULT_SUCCESS == result); 85 usleep(1000 + (rand() & 0xFFF)); 86 //usleep(1000); 87 //sleep(1); 88 (*myPlayerObject)->Destroy(myPlayerObject); 89 } 90 break; 91 92 default: 93 break; 94 95 } 96 //usleep(100000); 97 //break; 98 } 99 100 return NULL; 101} 102 103 104//const char * const uris[4] = {"wav/frog.wav", "wav/bach.wav", "wav/8days.wav", "wav/help16.wav"}; 105const char * const uris[4] = {"wav/frog.wav", "wav/frog.wav", "wav/frog.wav", "wav/frog.wav"}; 106 107// Main program 108 109int main(int argc, char **argv) 110{ 111 SLresult result; 112 113 // create engine 114 SLObjectItf engineObject; 115 result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); 116 assert(SL_RESULT_SUCCESS == result); 117 result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); 118 assert(SL_RESULT_SUCCESS == result); 119 SLEngineItf engineEngine; 120 result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); 121 assert(SL_RESULT_SUCCESS == result); 122 123 // create output mix 124 SLObjectItf mixObject; 125 result = (*engineEngine)->CreateOutputMix(engineEngine, &mixObject, 0, NULL, NULL); 126 assert(SL_RESULT_SUCCESS == result); 127 result = (*mixObject)->Realize(mixObject, SL_BOOLEAN_FALSE); 128 assert(SL_RESULT_SUCCESS == result); 129 130 // create threads 131 int i; 132 int ok; 133 for (i = 0; i < MAX_THREAD; ++i) { 134 ThreadArgument *ta = &thread_args[i]; 135 int r = rand(); 136 switch (r & 1) { 137#if 0 138 case 0: 139 ta->mObjectID = SL_OBJECTID_OUTPUTMIX; 140 ta->mURI = NULL; 141 ta->mEngineEngine = engineEngine; 142 ta->mMixObject = NULL; 143 ta->mCounter = 0; 144 break; 145 case 1: 146#endif 147 default: 148 ta->mObjectID = SL_OBJECTID_AUDIOPLAYER; 149 ta->mURI = (SLchar *) uris[(r >> 1) & 3]; 150 ta->mEngineEngine = engineEngine; 151 ta->mMixObject = mixObject; 152 ta->mCounter = 0; 153 break; 154 } 155 //pthread_mutex_lock(&mutex); 156 //pthread_mutex_unlock(&mutex); 157 ok = pthread_create(&threads[i], (const pthread_attr_t *) NULL, thread_start, 158 &thread_args[i]); 159 assert(0 == ok); 160 } 161 162 // let it run for a while 163 int j; 164 for (j = 0; j < 100; ++j) { 165 sleep(1); 166 for (i = 0; i < MAX_THREAD; ++i) { 167 ThreadArgument *ta = &thread_args[i]; 168 printf("[%d]=%lu ", j, ta->mCounter); 169 } 170 printf("\n"); 171 } 172 173 // signal threads that they should exit 174 timeToExit = 1; 175 176 for (j = 0; j < 3; ++j) { 177 sleep(1); 178 for (i = 0; i < MAX_THREAD; ++i) { 179 ThreadArgument *ta = &thread_args[i]; 180 printf("[%d]=%lu ", j, ta->mCounter); 181 } 182 printf("\n"); 183 } 184 185 // now wait for the threads to actually exit 186 for (i = 0; i < MAX_THREAD; ++i) { 187 ok = pthread_join(threads[i], NULL); 188 assert(0 == ok); 189 } 190 191 // tear down objects 192 (*mixObject)->Destroy(mixObject); 193 (*engineObject)->Destroy(engineObject); 194 195 return EXIT_SUCCESS; 196} 197