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