multithread.c revision 58432eb9cea995c69b4f905e68b38c1b8216edeb
1f933441648ef6a71dee783d733aac17b9508b452Andreas Huber/* 2f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Copyright (C) 2010 The Android Open Source Project 3f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * 4f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * you may not use this file except in compliance with the License. 6f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * You may obtain a copy of the License at 7f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * 8f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * 10f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * Unless required by applicable law or agreed to in writing, software 11f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * See the License for the specific language governing permissions and 14f933441648ef6a71dee783d733aac17b9508b452Andreas Huber * limitations under the License. 15f933441648ef6a71dee783d733aac17b9508b452Andreas Huber */ 16f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 17f933441648ef6a71dee783d733aac17b9508b452Andreas Huber// Multiple threads create and destroy objects 18f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 19f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include "SLES/OpenSLES.h" 20f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <assert.h> 21f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <pthread.h> 22f933441648ef6a71dee783d733aac17b9508b452Andreas Huber//#include <string.h> 231173118eace0e9e347cb007f0da817cee87579edGlenn Kasten#include <stdio.h> 24f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <stdlib.h> 25f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#include <unistd.h> 26f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 27404fced9bfa8fa423ee210a271ca051ffd1bec13Chong Zhangtypedef struct { 28f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SLuint32 mObjectID; 2943c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber SLchar *mURI; 30f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SLEngineItf mEngineEngine; 31f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SLObjectItf mMixObject; 32f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SLuint32 mCounter; 33f933441648ef6a71dee783d733aac17b9508b452Andreas Huber} ThreadArgument; 349b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber 359b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Hubervolatile int timeToExit = 0; 3643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber#define MAX_THREAD 10 37f933441648ef6a71dee783d733aac17b9508b452Andreas Huberpthread_t threads[MAX_THREAD]; 389575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas HuberThreadArgument thread_args[MAX_THREAD]; 395bc087c573c70c84c6a39946457590b42d392a33Andreas Huber 409575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huberpthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 411b86fe063badb5f28c467ade39be0f4008688947Andreas Huber 421b86fe063badb5f28c467ade39be0f4008688947Andreas Hubervoid *thread_start(void *param) 431b86fe063badb5f28c467ade39be0f4008688947Andreas Huber{ 445bc087c573c70c84c6a39946457590b42d392a33Andreas Huber //pthread_mutex_lock(&mutex); 459575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber //pthread_mutex_unlock(&mutex); 469575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber ThreadArgument *ta = (ThreadArgument *) param; 479575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber 48afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber while (!timeToExit) { 4957a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber SLresult result; 508ba01021b573889802e67e029225a96f0dfa471aAndy McFadden 5157a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber ++ta->mCounter; 52f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (ta->mObjectID) { 53f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case SL_OBJECTID_OUTPUTMIX: 54f933441648ef6a71dee783d733aac17b9508b452Andreas Huber { 5543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber SLObjectItf myMixObject; 5643c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber result = (*ta->mEngineEngine)->CreateOutputMix(ta->mEngineEngine, &myMixObject, 0, NULL, 5743c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber NULL); 5843c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber assert(SL_RESULT_SUCCESS == result); 591aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber result = (*myMixObject)->Realize(myMixObject, SL_BOOLEAN_FALSE); 601aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber assert(SL_RESULT_SUCCESS == result); 6143c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber (*myMixObject)->Destroy(myMixObject); 6243c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber } 6343c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber break; 640d268a3cae145afb2720c88ae38fb81550be5584James Dong 65dcb89b3b505522efde173c105a851c412f947178Chong Zhang case SL_OBJECTID_AUDIOPLAYER: 66dcb89b3b505522efde173c105a851c412f947178Chong Zhang { 670d268a3cae145afb2720c88ae38fb81550be5584James Dong SLDataLocator_URI locURI = {SL_DATALOCATOR_URI, ta->mURI}; 68f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SLDataFormat_MIME dfMIME = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED}; 69f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SLDataSource audioSrc = {&locURI, &dfMIME}; 70f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SLDataLocator_OutputMix locOutputMix = {SL_DATALOCATOR_OUTPUTMIX, ta->mMixObject}; 71f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SLDataSink audioSnk = {&locOutputMix, NULL}; 72f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SLObjectItf myPlayerObject; 73840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber result = (*ta->mEngineEngine)->CreateAudioPlayer(ta->mEngineEngine, &myPlayerObject, 74840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber &audioSrc, &audioSnk, 0, NULL, NULL); 75840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber assert(SL_RESULT_SUCCESS == result); 76840667883fd09d44015716d79bc3ac4d60edc0f0Andreas Huber result = (*myPlayerObject)->Realize(myPlayerObject, SL_BOOLEAN_FALSE); 77f933441648ef6a71dee783d733aac17b9508b452Andreas Huber assert(SL_RESULT_SUCCESS == result); 78f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SLPlayItf playerPlay; 79bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia result = (*myPlayerObject)->GetInterface(myPlayerObject, SL_IID_PLAY, &playerPlay); 80a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang assert(SL_RESULT_SUCCESS == result); 81afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PAUSED); 825bc087c573c70c84c6a39946457590b42d392a33Andreas Huber assert(SL_RESULT_SUCCESS == result); 835bc087c573c70c84c6a39946457590b42d392a33Andreas Huber usleep(1000 + (rand() & 0xFFF)); 84afed0e1fa37473a4cd30018577b560acc79d9a3fAndreas Huber //usleep(1000); 855bc087c573c70c84c6a39946457590b42d392a33Andreas Huber //sleep(1); 86a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber (*myPlayerObject)->Destroy(myPlayerObject); 87a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber } 8857a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber break; 8914f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber 9014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber default: 91a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber break; 92f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 93f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 94078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber //usleep(100000); 959575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber //break; 96078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber } 97078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 98078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber return NULL; 99078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber} 100078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 101078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 102078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber//const char * const uris[4] = {"wav/frog.wav", "wav/bach.wav", "wav/8days.wav", "wav/help16.wav"}; 103a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhangconst char * const uris[4] = {"wav/frog.wav", "wav/frog.wav", "wav/frog.wav", "wav/frog.wav"}; 104078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 105078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber// Main program 106078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber 107078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huberint main(int argc, char **argv) 108078cfcf7cce9185ec7559910d08b0bc02bfc88a3Andreas Huber{ 109b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber SLresult result; 110b5f25f005bc1d3ae35f45b58c88345e183dc336dAndreas Huber 111dcb89b3b505522efde173c105a851c412f947178Chong Zhang // create engine 112dcb89b3b505522efde173c105a851c412f947178Chong Zhang SLObjectItf engineObject; 113f933441648ef6a71dee783d733aac17b9508b452Andreas Huber result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL); 114f933441648ef6a71dee783d733aac17b9508b452Andreas Huber assert(SL_RESULT_SUCCESS == result); 11543c3e6ce02215ca99d506458f596cb1211639f29Andreas Huber result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE); 1169b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber assert(SL_RESULT_SUCCESS == result); 1179b80c2bdb205bc143104f54d0743b6eedd67b14eAndreas Huber SLEngineItf engineEngine; 1185bc087c573c70c84c6a39946457590b42d392a33Andreas Huber result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine); 1199575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber assert(SL_RESULT_SUCCESS == result); 1201173118eace0e9e347cb007f0da817cee87579edGlenn Kasten 121f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // create output mix 122f933441648ef6a71dee783d733aac17b9508b452Andreas Huber SLObjectItf mixObject; 1233fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber result = (*engineEngine)->CreateOutputMix(engineEngine, &mixObject, 0, NULL, NULL); 124bc2fb720bbd0acd122bacc67e844e982d068f6f9Wei Jia assert(SL_RESULT_SUCCESS == result); 125f933441648ef6a71dee783d733aac17b9508b452Andreas Huber result = (*mixObject)->Realize(mixObject, SL_BOOLEAN_FALSE); 126a7fa1d9530b6870f2c7850e3025d7db963661803Chong Zhang assert(SL_RESULT_SUCCESS == result); 127f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 128095248375e29adde961ec2a44989ecb3a6dda6a2Lajos Molnar // create threads 129f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int i; 130a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber int ok; 131a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber for (i = 0; i < MAX_THREAD; ++i) { 132f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ThreadArgument *ta = &thread_args[i]; 133f933441648ef6a71dee783d733aac17b9508b452Andreas Huber int r = rand(); 134f933441648ef6a71dee783d733aac17b9508b452Andreas Huber switch (r & 1) { 1355bc087c573c70c84c6a39946457590b42d392a33Andreas Huber#if 0 1361aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber case 0: 1375bc087c573c70c84c6a39946457590b42d392a33Andreas Huber ta->mObjectID = SL_OBJECTID_OUTPUTMIX; 138b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber ta->mURI = NULL; 139d3b0bbb8a37f90fba84eb4e95c58aa0fec6c51e7Robert Shih ta->mEngineEngine = engineEngine; 140b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber ta->mMixObject = NULL; 141f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ta->mCounter = 0; 142f933441648ef6a71dee783d733aac17b9508b452Andreas Huber break; 143f933441648ef6a71dee783d733aac17b9508b452Andreas Huber case 1: 144f933441648ef6a71dee783d733aac17b9508b452Andreas Huber#endif 1451aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber default: 1463831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber ta->mObjectID = SL_OBJECTID_AUDIOPLAYER; 1473831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber ta->mURI = (SLchar *) uris[(r >> 1) & 3]; 1483831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber ta->mEngineEngine = engineEngine; 149f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ta->mMixObject = mixObject; 150f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ta->mCounter = 0; 1516e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber break; 1526e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber } 1536e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber //pthread_mutex_lock(&mutex); 1546e3d311b6631b12aac2879d1b08c3534aece78b1Andreas Huber //pthread_mutex_unlock(&mutex); 155f933441648ef6a71dee783d733aac17b9508b452Andreas Huber ok = pthread_create(&threads[i], (const pthread_attr_t *) NULL, thread_start, 156f933441648ef6a71dee783d733aac17b9508b452Andreas Huber &thread_args[i]); 157f933441648ef6a71dee783d733aac17b9508b452Andreas Huber assert(0 == ok); 15832f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber } 15932f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber 16032f3cefa373cd55e63deda36ca9d07c7fe22eaafAndreas Huber // let it run for a while 1613fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber int j; 1623fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber for (j = 0; j < 100; ++j) { 1633fe62150fa3dd6d25cb84aad80bc9e27ddd16c45Andreas Huber sleep(1); 1640d268a3cae145afb2720c88ae38fb81550be5584James Dong for (i = 0; i < MAX_THREAD; ++i) { 1650d268a3cae145afb2720c88ae38fb81550be5584James Dong ThreadArgument *ta = &thread_args[i]; 16657a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber printf("[%d]=%u ", j, ta->mCounter); 16757a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber } 1685bc087c573c70c84c6a39946457590b42d392a33Andreas Huber printf("\n"); 169f933441648ef6a71dee783d733aac17b9508b452Andreas Huber } 170f933441648ef6a71dee783d733aac17b9508b452Andreas Huber 171f933441648ef6a71dee783d733aac17b9508b452Andreas Huber // signal threads that they should exit 172f933441648ef6a71dee783d733aac17b9508b452Andreas Huber timeToExit = 1; 173dcb89b3b505522efde173c105a851c412f947178Chong Zhang 174f933441648ef6a71dee783d733aac17b9508b452Andreas Huber for (j = 0; j < 3; ++j) { 1753831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber sleep(1); 1763831a066bcf1019864a94d2bc7b4c9241efc5c22Andreas Huber for (i = 0; i < MAX_THREAD; ++i) { 1771aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber ThreadArgument *ta = &thread_args[i]; 1781aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber printf("[%d]=%u ", j, ta->mCounter); 1791aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber } 1801aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber printf("\n"); 1811aef211b4e5dc952081727bfd2318b2cb5ca4506Andreas Huber } 18253df1a460bcfdd129ca2bc416dee2009e35c042eAndreas Huber 183b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber // now wait for the threads to actually exit 184b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber for (i = 0; i < MAX_THREAD; ++i) { 185b7c8e91880463ff4981e3e53e98e45d68e2fe374Andreas Huber ok = pthread_join(threads[i], NULL); 186a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber assert(0 == ok); 187a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber } 188a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber 189a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber // tear down objects 19014f7672b5d450ed26a06fd3bb3ce045ea78b11b2Andreas Huber (*mixObject)->Destroy(mixObject); 191a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber (*engineObject)->Destroy(engineObject); 192a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber 19357a339cdb7524f883de3ceb364c0b5606df0c610Andreas Huber return EXIT_SUCCESS; 194a1f8ab0ad670c30e57f3f072df13df66fe4f4910Andreas Huber} 1959575c96b6e418914e2ffc6741ecc8d71e3968dbeAndreas Huber