-
Lost with wrong output
I can't see how this code isn't getting the output which should be:
buffer elem = -378931907
buffer elem = 1991142473
buffer elem = -2051466334
buffer elem = -1945167320
buffer elem = 1080018178
Rather than:
buffer elem = 1343403155
buffer elem = 225005971
buffer elem = 1270463783
buffer elem = -1162132598
buffer elem = 636863738
The thread is suppose to be suspended given: if((b->in+1)%b->max_buffer_size == b->out) then await it's signal from get_buffer to add more to the buffer. The maximum buffer size has been initialised to 5.
What is the source of this problem?
from put buffer = -378931907
from put buffer = 1991142473
from put buffer = -2051466334
from put buffer = -1945167320
from put buffer = 1080018178
from put buffer = 1343403155
from put buffer = 225005971
from put buffer = 1270463783
from put buffer = -1162132598
from put buffer = 636863738
Code:
void init_buffer(bufferQueue *b, semaphore s, int min, int max)
{
b->buffer_array = malloc(max*sizeof(int));
b->in = 0;
b->out = 0;
b->min_buffer_size = min;
b->max_buffer_size = max;
b->sem = s;
}
Code:
void put_buffer(bufferQueue *b, int v)
{
if((b->in+1)%b->max_buffer_size == b->out)
{
semWait(&(b->sem));
}
b->buffer_array[b->in] = v;
printf("from put buffer = %d\n", b->buffer_array[b->in]);
b->in = (b->in+1)%b->max_buffer_size;
semSignal(&(b->sem));
}
Code:
void *producer(void* cb)
{
printf("testing\n");
bufferQueue *cbuffer = (bufferQueue *)cb;
int i;
for(i = 0; i < 10; i++)
{
put_buffer(cbuffer, randomNum());
}
for(i = 0; i < 5; i++)
{
printf("buffer elem = %d\n", cbuffer->buffer_array[i]);
}
destroy_buffer(cbuffer);
return cb;
}
int main(void)
{
semaphore sem;
bufferQueue cbuffer;
pthread_t thread;
init_sem(&sem);
init_buffer(&cbuffer, sem, 0, 5);
pthread_create(&thread, NULL, producer, (void*)(&cbuffer));
-
The top six lines of what you expect your output to be look the same as the top six lines of whatever that next block of output is. What exactly is the problem?
Edit: Actually, why is it you think you're going to get a specific set of numbers? You are calling a RNG you know.
Quzah.
-
The buffer should suspend when it is "full" and therefore not being overwritten by the last output block.
-
And where is it you think you're doing that?
% max will never == max
Quzah.
-
I am trying to follow this logic for a full buffer from a c++ tutorial and i can't see how my code is different. :(
From C++Course: Circular Buffer
if ((next + 1) % array.length == first)
Mine:
if((b->in+1)%b->max_buffer_size == b->out)
-
Ok, I thought you were comparing it to max. Alright, well it would help if your variables had meaningful names. 'out' doesn't actually mean anything to me. So 'out' is actually the number of the first item in the buffer? Why didn't you just call it first? Anyway...
1. Are you supposed to be just passing a copy of your semaphore around? Because you're passing by value a lot. I don't know if that matters for what you're doing.
2. Your wait function isn't shown.
3. My guess is it waits for a split second, and then just continues on with the rest of the assignment.
4. If you want it to be easier to see what's going on, lose the call to rand and just increment a variable so you can easily follow the sequence of events. x++ is much easier to follow than rand() ten digit numbers.
5. You have five different code blocks in as many files. Try making the smallest single file working example you can, it's easier to troubleshoot that way.
Quzah.
-
using i instead of random()
from put buffer = 0
from put buffer = 1
from put buffer = 2
from put buffer = 3
from put buffer = 4
from put buffer = 5
from put buffer = 6
from put buffer = 7
from put buffer = 8
from put buffer = 9
buffer elem = 5
buffer elem = 6
buffer elem = 7
buffer elem = 8
buffer elem = 9
-
Looks right to me. What is it supposed to do? I assume you're actually popping things off of your queue some place? In which case, your output looks fine to me. If not, then it's doing like I said, and not actually pausing--or rather, it's pausing, but it's not stopping. You do know you don't have an else there... So in either event, the output looks like what I'd expect it to.
I'm not sure you're actually looking at your queue function. Sure, it's pausing, but then what? Then it goes ahead and queues it up anyway. What are you expecting it to do there? That output looks normal to me. You're saying:
"queue these 10 things"
"print the queue"
And your queue can only hold five, so yes, it's going to hold the last five. How is that different than what you expect it to do, and why do you think it's going to do whatever you're expecting it to do? (a - explain what you think should happen, b - show the code that's supposedly making it do what you think it should be doing)
Quzah.
-
The semWait should suspend the producer thread until it is signaled by
get_buffer(). My semaphore's purpose is to protect buffer contents from being incorrectly overwritten and stop reading of an empty buffer.
When the if conditions are satisfied shouldn't the function pause as well as the producer thread? Then when signaled, the rest of the get_buffer() or put_buffer() functions execute the remain code after if conditions?
put_buffer()
Code:
void put_buffer(bufferQueue *b, int v)
{
if((b->in+1)%b->max_buffer_size == b->out)
{
semWait(&(b->sem));
}
b->buffer_array[b->in] = v;
printf("from put buffer = %d\n", b->buffer_array[b->in]);
b->in = (b->in+1)%b->max_buffer_size;
semSignal(&(b->sem));
}
get_buffer()
Code:
int get_buffer(bufferQueue *b)
{
if(b->in == b->out)
{
semWait(&(b->sem));
}
return b->buffer_array[b->out];
b->out = (b->out+1)%b->max_buffer_size;
semSignal(&(b->sem));
}