xref: /aosp_15_r20/external/deqp/framework/delibs/destream/deThreadStream.c (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Stream Library
3*35238bceSAndroid Build Coastguard Worker  * ---------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief Buffered and threaded input and output streams
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "deThreadStream.h"
25*35238bceSAndroid Build Coastguard Worker #include "deStreamCpyThread.h"
26*35238bceSAndroid Build Coastguard Worker #include "deRingbuffer.h"
27*35238bceSAndroid Build Coastguard Worker #include "stdlib.h"
28*35238bceSAndroid Build Coastguard Worker 
29*35238bceSAndroid Build Coastguard Worker typedef struct deThreadInStream_s
30*35238bceSAndroid Build Coastguard Worker {
31*35238bceSAndroid Build Coastguard Worker     deRingbuffer *ringbuffer;
32*35238bceSAndroid Build Coastguard Worker     deInStream *input;
33*35238bceSAndroid Build Coastguard Worker     deInStream consumerStream;
34*35238bceSAndroid Build Coastguard Worker     deOutStream producerStream;
35*35238bceSAndroid Build Coastguard Worker     deThread thread;
36*35238bceSAndroid Build Coastguard Worker     int bufferSize;
37*35238bceSAndroid Build Coastguard Worker } deThreadInStream;
38*35238bceSAndroid Build Coastguard Worker 
39*35238bceSAndroid Build Coastguard Worker typedef struct deThreadOutStream_s
40*35238bceSAndroid Build Coastguard Worker {
41*35238bceSAndroid Build Coastguard Worker     deRingbuffer *ringbuffer;
42*35238bceSAndroid Build Coastguard Worker     deInStream consumerStream;
43*35238bceSAndroid Build Coastguard Worker     deOutStream producerStream;
44*35238bceSAndroid Build Coastguard Worker     deStreamCpyThread *thread;
45*35238bceSAndroid Build Coastguard Worker } deThreadOutStream;
46*35238bceSAndroid Build Coastguard Worker 
inStreamCopy(void * arg)47*35238bceSAndroid Build Coastguard Worker static void inStreamCopy(void *arg)
48*35238bceSAndroid Build Coastguard Worker {
49*35238bceSAndroid Build Coastguard Worker     deThreadInStream *threadStream = (deThreadInStream *)arg;
50*35238bceSAndroid Build Coastguard Worker 
51*35238bceSAndroid Build Coastguard Worker     uint8_t *buffer = malloc(sizeof(uint8_t) * (size_t)threadStream->bufferSize);
52*35238bceSAndroid Build Coastguard Worker 
53*35238bceSAndroid Build Coastguard Worker     for (;;)
54*35238bceSAndroid Build Coastguard Worker     {
55*35238bceSAndroid Build Coastguard Worker         int32_t read              = 0;
56*35238bceSAndroid Build Coastguard Worker         int32_t written           = 0;
57*35238bceSAndroid Build Coastguard Worker         deStreamResult readResult = DE_STREAMRESULT_ERROR;
58*35238bceSAndroid Build Coastguard Worker 
59*35238bceSAndroid Build Coastguard Worker         readResult = deInStream_read(threadStream->input, buffer, threadStream->bufferSize, &read);
60*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(readResult != DE_STREAMRESULT_ERROR);
61*35238bceSAndroid Build Coastguard Worker         while (written < read)
62*35238bceSAndroid Build Coastguard Worker         {
63*35238bceSAndroid Build Coastguard Worker             int32_t wrote = 0;
64*35238bceSAndroid Build Coastguard Worker 
65*35238bceSAndroid Build Coastguard Worker             /* \todo [mika] Handle errors */
66*35238bceSAndroid Build Coastguard Worker             deOutStream_write(&(threadStream->producerStream), buffer, read - written, &wrote);
67*35238bceSAndroid Build Coastguard Worker 
68*35238bceSAndroid Build Coastguard Worker             written += wrote;
69*35238bceSAndroid Build Coastguard Worker         }
70*35238bceSAndroid Build Coastguard Worker 
71*35238bceSAndroid Build Coastguard Worker         if (readResult == DE_STREAMRESULT_END_OF_STREAM)
72*35238bceSAndroid Build Coastguard Worker         {
73*35238bceSAndroid Build Coastguard Worker             break;
74*35238bceSAndroid Build Coastguard Worker         }
75*35238bceSAndroid Build Coastguard Worker     }
76*35238bceSAndroid Build Coastguard Worker 
77*35238bceSAndroid Build Coastguard Worker     deOutStream_flush(&(threadStream->producerStream));
78*35238bceSAndroid Build Coastguard Worker     deRingbuffer_stop(threadStream->ringbuffer);
79*35238bceSAndroid Build Coastguard Worker     free(buffer);
80*35238bceSAndroid Build Coastguard Worker }
81*35238bceSAndroid Build Coastguard Worker 
threadInStream_read(deStreamData * stream,void * buf,int32_t bufSize,int32_t * numRead)82*35238bceSAndroid Build Coastguard Worker static deStreamResult threadInStream_read(deStreamData *stream, void *buf, int32_t bufSize, int32_t *numRead)
83*35238bceSAndroid Build Coastguard Worker {
84*35238bceSAndroid Build Coastguard Worker     deThreadInStream *threadStream = (deThreadInStream *)stream;
85*35238bceSAndroid Build Coastguard Worker     return deInStream_read(&(threadStream->consumerStream), buf, bufSize, numRead);
86*35238bceSAndroid Build Coastguard Worker }
87*35238bceSAndroid Build Coastguard Worker 
threadInStream_getError(deStreamData * stream)88*35238bceSAndroid Build Coastguard Worker static const char *threadInStream_getError(deStreamData *stream)
89*35238bceSAndroid Build Coastguard Worker {
90*35238bceSAndroid Build Coastguard Worker     deThreadInStream *threadStream = (deThreadInStream *)stream;
91*35238bceSAndroid Build Coastguard Worker 
92*35238bceSAndroid Build Coastguard Worker     /* \todo [mika] Add handling for errors on thread stream */
93*35238bceSAndroid Build Coastguard Worker     return deInStream_getError(&(threadStream->consumerStream));
94*35238bceSAndroid Build Coastguard Worker }
95*35238bceSAndroid Build Coastguard Worker 
threadInStream_getStatus(deStreamData * stream)96*35238bceSAndroid Build Coastguard Worker static deStreamStatus threadInStream_getStatus(deStreamData *stream)
97*35238bceSAndroid Build Coastguard Worker {
98*35238bceSAndroid Build Coastguard Worker     deThreadInStream *threadStream = (deThreadInStream *)stream;
99*35238bceSAndroid Build Coastguard Worker 
100*35238bceSAndroid Build Coastguard Worker     /* \todo [mika] Add handling for status on thread stream */
101*35238bceSAndroid Build Coastguard Worker     return deInStream_getStatus(&(threadStream->consumerStream));
102*35238bceSAndroid Build Coastguard Worker }
103*35238bceSAndroid Build Coastguard Worker 
104*35238bceSAndroid Build Coastguard Worker /* \note [mika] Used by both in and out stream */
threadStream_deinit(deStreamData * stream)105*35238bceSAndroid Build Coastguard Worker static deStreamResult threadStream_deinit(deStreamData *stream)
106*35238bceSAndroid Build Coastguard Worker {
107*35238bceSAndroid Build Coastguard Worker     deThreadInStream *threadStream = (deThreadInStream *)stream;
108*35238bceSAndroid Build Coastguard Worker 
109*35238bceSAndroid Build Coastguard Worker     deRingbuffer_stop(threadStream->ringbuffer);
110*35238bceSAndroid Build Coastguard Worker 
111*35238bceSAndroid Build Coastguard Worker     deThread_join(threadStream->thread);
112*35238bceSAndroid Build Coastguard Worker     deThread_destroy(threadStream->thread);
113*35238bceSAndroid Build Coastguard Worker 
114*35238bceSAndroid Build Coastguard Worker     deOutStream_deinit(&(threadStream->producerStream));
115*35238bceSAndroid Build Coastguard Worker     deInStream_deinit(&(threadStream->consumerStream));
116*35238bceSAndroid Build Coastguard Worker 
117*35238bceSAndroid Build Coastguard Worker     deRingbuffer_destroy(threadStream->ringbuffer);
118*35238bceSAndroid Build Coastguard Worker 
119*35238bceSAndroid Build Coastguard Worker     return DE_STREAMRESULT_SUCCESS;
120*35238bceSAndroid Build Coastguard Worker }
121*35238bceSAndroid Build Coastguard Worker 
122*35238bceSAndroid Build Coastguard Worker static const deIOStreamVFTable threadInStreamVFTable = {
123*35238bceSAndroid Build Coastguard Worker     threadInStream_read, DE_NULL, threadInStream_getError, DE_NULL, threadStream_deinit, threadInStream_getStatus};
124*35238bceSAndroid Build Coastguard Worker 
deThreadInStream_init(deInStream * stream,deInStream * input,int ringbufferBlockSize,int ringbufferBlockCount)125*35238bceSAndroid Build Coastguard Worker void deThreadInStream_init(deInStream *stream, deInStream *input, int ringbufferBlockSize, int ringbufferBlockCount)
126*35238bceSAndroid Build Coastguard Worker {
127*35238bceSAndroid Build Coastguard Worker     deThreadInStream *threadStream = DE_NULL;
128*35238bceSAndroid Build Coastguard Worker 
129*35238bceSAndroid Build Coastguard Worker     threadStream = malloc(sizeof(deThreadInStream));
130*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(threadStream);
131*35238bceSAndroid Build Coastguard Worker 
132*35238bceSAndroid Build Coastguard Worker     threadStream->ringbuffer = deRingbuffer_create(ringbufferBlockSize, ringbufferBlockCount);
133*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(threadStream->ringbuffer);
134*35238bceSAndroid Build Coastguard Worker 
135*35238bceSAndroid Build Coastguard Worker     threadStream->bufferSize = ringbufferBlockSize;
136*35238bceSAndroid Build Coastguard Worker     threadStream->input      = input;
137*35238bceSAndroid Build Coastguard Worker     deProducerStream_init(&(threadStream->producerStream), threadStream->ringbuffer);
138*35238bceSAndroid Build Coastguard Worker     deConsumerStream_init(&(threadStream->consumerStream), threadStream->ringbuffer);
139*35238bceSAndroid Build Coastguard Worker 
140*35238bceSAndroid Build Coastguard Worker     threadStream->thread        = deThread_create(inStreamCopy, threadStream, DE_NULL);
141*35238bceSAndroid Build Coastguard Worker     stream->ioStream.vfTable    = &threadInStreamVFTable;
142*35238bceSAndroid Build Coastguard Worker     stream->ioStream.streamData = threadStream;
143*35238bceSAndroid Build Coastguard Worker }
144*35238bceSAndroid Build Coastguard Worker 
threadOutStream_write(deStreamData * stream,const void * buf,int32_t bufSize,int32_t * numWritten)145*35238bceSAndroid Build Coastguard Worker static deStreamResult threadOutStream_write(deStreamData *stream, const void *buf, int32_t bufSize, int32_t *numWritten)
146*35238bceSAndroid Build Coastguard Worker {
147*35238bceSAndroid Build Coastguard Worker     deThreadOutStream *threadStream = (deThreadOutStream *)stream;
148*35238bceSAndroid Build Coastguard Worker     return deOutStream_write(&(threadStream->producerStream), buf, bufSize, numWritten);
149*35238bceSAndroid Build Coastguard Worker }
150*35238bceSAndroid Build Coastguard Worker 
threadOutStream_getError(deStreamData * stream)151*35238bceSAndroid Build Coastguard Worker static const char *threadOutStream_getError(deStreamData *stream)
152*35238bceSAndroid Build Coastguard Worker {
153*35238bceSAndroid Build Coastguard Worker     deThreadOutStream *threadStream = (deThreadOutStream *)stream;
154*35238bceSAndroid Build Coastguard Worker 
155*35238bceSAndroid Build Coastguard Worker     /* \todo [mika] Add handling for errors on thread stream */
156*35238bceSAndroid Build Coastguard Worker     return deOutStream_getError(&(threadStream->producerStream));
157*35238bceSAndroid Build Coastguard Worker }
158*35238bceSAndroid Build Coastguard Worker 
threadOutStream_getStatus(deStreamData * stream)159*35238bceSAndroid Build Coastguard Worker static deStreamStatus threadOutStream_getStatus(deStreamData *stream)
160*35238bceSAndroid Build Coastguard Worker {
161*35238bceSAndroid Build Coastguard Worker     deThreadOutStream *threadStream = (deThreadOutStream *)stream;
162*35238bceSAndroid Build Coastguard Worker 
163*35238bceSAndroid Build Coastguard Worker     /* \todo [mika] Add handling for errors on thread stream */
164*35238bceSAndroid Build Coastguard Worker     return deOutStream_getStatus(&(threadStream->producerStream));
165*35238bceSAndroid Build Coastguard Worker }
166*35238bceSAndroid Build Coastguard Worker 
threadOutStream_flush(deStreamData * stream)167*35238bceSAndroid Build Coastguard Worker static deStreamResult threadOutStream_flush(deStreamData *stream)
168*35238bceSAndroid Build Coastguard Worker {
169*35238bceSAndroid Build Coastguard Worker     deThreadOutStream *threadStream = (deThreadOutStream *)stream;
170*35238bceSAndroid Build Coastguard Worker 
171*35238bceSAndroid Build Coastguard Worker     return deOutStream_flush(&(threadStream->producerStream));
172*35238bceSAndroid Build Coastguard Worker }
173*35238bceSAndroid Build Coastguard Worker 
174*35238bceSAndroid Build Coastguard Worker static const deIOStreamVFTable threadOutStreamVFTable = {DE_NULL,
175*35238bceSAndroid Build Coastguard Worker                                                          threadOutStream_write,
176*35238bceSAndroid Build Coastguard Worker                                                          threadOutStream_getError,
177*35238bceSAndroid Build Coastguard Worker                                                          threadOutStream_flush,
178*35238bceSAndroid Build Coastguard Worker                                                          threadStream_deinit,
179*35238bceSAndroid Build Coastguard Worker                                                          threadOutStream_getStatus};
180*35238bceSAndroid Build Coastguard Worker 
deThreadOutStream_init(deOutStream * stream,deOutStream * output,int ringbufferBlockSize,int ringbufferBlockCount)181*35238bceSAndroid Build Coastguard Worker void deThreadOutStream_init(deOutStream *stream, deOutStream *output, int ringbufferBlockSize, int ringbufferBlockCount)
182*35238bceSAndroid Build Coastguard Worker {
183*35238bceSAndroid Build Coastguard Worker     deThreadOutStream *threadStream = DE_NULL;
184*35238bceSAndroid Build Coastguard Worker 
185*35238bceSAndroid Build Coastguard Worker     threadStream = malloc(sizeof(deThreadOutStream));
186*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(threadStream);
187*35238bceSAndroid Build Coastguard Worker 
188*35238bceSAndroid Build Coastguard Worker     threadStream->ringbuffer = deRingbuffer_create(ringbufferBlockSize, ringbufferBlockCount);
189*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(threadStream->ringbuffer);
190*35238bceSAndroid Build Coastguard Worker 
191*35238bceSAndroid Build Coastguard Worker     deProducerStream_init(&(threadStream->producerStream), threadStream->ringbuffer);
192*35238bceSAndroid Build Coastguard Worker     deConsumerStream_init(&(threadStream->consumerStream), threadStream->ringbuffer);
193*35238bceSAndroid Build Coastguard Worker 
194*35238bceSAndroid Build Coastguard Worker     threadStream->thread     = deStreamCpyThread_create(&(threadStream->consumerStream), output, ringbufferBlockSize);
195*35238bceSAndroid Build Coastguard Worker     stream->ioStream.vfTable = &threadOutStreamVFTable;
196*35238bceSAndroid Build Coastguard Worker     stream->ioStream.streamData = threadStream;
197*35238bceSAndroid Build Coastguard Worker }
198