Problems I see:
1) pthread_exit() doesn't return, close(gpio_fd) never called - just remove all calls to pthread_exit()
2) Undefined behavior due to calling pthread_cond_wait() without locking mutex first
3) Unsynchronized access to globals by readval() - mutex is never locked.
4) Remove all calls to time() and usleep() - they aren't needed - use a better "stopping strategy" in readval()
Here is a very simple implementation of Salem's suggestion from your previous thread: http://cboard.cprogramming.com/showthread.php?p=743534
Code:
#include <stdio.h>
#include <pthread.h>
void* read_thread(void *arg);
void* write_thread(void *arg);
#define NCH 3
#define WRITE_SZ 512 // # of bytes to accumulate before writing
#define NSAMPLES (WRITE_SZ / (NCH * sizeof(int)))
#define SETS_TO_READ 5 // # of times to read NSAMPLES before quiting
int g_buff1[NSAMPLES * NCH];
int g_buff2[NSAMPLES * NCH];
int *g_write_buff;
int g_exit = 0;
const char *g_output_file = "samples.txt";
pthread_mutex_t g_mux = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t g_cond = PTHREAD_COND_INITIALIZER;
// simulate reading from ADC
int ADC_TxRx(int ch)
{
static int s_ADC_data[NCH] = {0, 0, 0};
return ++s_ADC_data[ch];
}//ADC_TxRx
int main(void)
{
pthread_t reader_thread,
writer_thread;
pthread_create(&writer_thread, NULL, &write_thread, NULL);
pthread_create(&reader_thread, NULL, &read_thread, NULL);
pthread_join(reader_thread, NULL);
pthread_join(writer_thread, NULL);
printf("main(): All threads done.\n"
"SETS_TO_READ = %d, NSAMPLES = %d, WRITE_SZ = %d\n",
SETS_TO_READ, NSAMPLES, WRITE_SZ);
pthread_mutex_destroy(&g_mux);
pthread_cond_destroy(&g_cond);
return 0;
}//main
void* read_thread(void *arg)
{
int *cur_buff = g_buff1,
*last_buff = g_buff2,
*tmp_buff;
int nSet;
for (nSet = 0; nSet < SETS_TO_READ; ++nSet)
{
int nSample, i = 0;
for (nSample = 0; nSample < NSAMPLES; ++nSample)
{
int ch;
for (ch = 0; ch < NCH; ++ch)
cur_buff[i++] = ADC_TxRx(ch);
}//for
// signal write thread to write g_write_buff
pthread_mutex_lock(&g_mux);
{
g_write_buff = cur_buff;
pthread_cond_broadcast(&g_cond);
}//mutex block
pthread_mutex_unlock(&g_mux);
// swap buffers
tmp_buff = cur_buff;
cur_buff = last_buff;
last_buff = tmp_buff;
}//for
// signal write thread to exit
pthread_mutex_lock(&g_mux);
{
g_exit = 1;
pthread_cond_broadcast(&g_cond);
}//mutex block
pthread_mutex_unlock(&g_mux);
return 0;
}//read_thread
void* write_thread(void *arg)
{
FILE *out = fopen(g_output_file, "w");
pthread_mutex_lock(&g_mux);
{
for (;;)
{
int nSample, i;
pthread_cond_wait(&g_cond, &g_mux);
if (g_exit)
break;
i = 0;
for (nSample = 0; nSample < NSAMPLES; ++nSample)
{
fprintf(out, "%d, %d, %d\n",
g_write_buff[i++], // 3 channels per sample
g_write_buff[i++],
g_write_buff[i++]);
}//for
// ensure writes go to disk
fflush(out);
}//for
}//mutex block
pthread_mutex_unlock(&g_mux);
fclose(out);
return 0;
}//write_thread
This is as simple as it gets (minus error checking). The downside is that the reading bandwidth is limited by the writing bandwidth, as I mentioned in the previous thread.
gg