Skip to content
This repository has been archived by the owner on Mar 28, 2022. It is now read-only.

a palliative for race condition problem #88

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ CXX=g++
CC=gcc
#OPTFLAGS=-g -O0
OPTFLAGS=-O3 -DBOOST_UBLAS_NDEBUG -DNDEBUG
MYFLAGS=-DNO_THREADS
BOOST_CFLAGS=-I/usr/local/include/boost-1_35
TAGLIB_CFLAGS=`taglib-config --cflags`
TAGLIB_LIBS=`taglib-config --libs`
CXXFLAGS=-Wall $(BOOST_CFLAGS) $(TAGLIB_CFLAGS) -fPIC $(OPTFLAGS)
CXXFLAGS=-Wall $(BOOST_CFLAGS) $(TAGLIB_CFLAGS) -fPIC $(OPTFLAGS) $(MYFLAGS)
CFLAGS=-Wall -fPIC $(OPTFLAGS)
LDFLAGS=$(TAGLIB_LIBS) -lz -lpthread $(OPTFLAGS)
LIBNAME=libcodegen.so
Expand Down
42 changes: 26 additions & 16 deletions src/main.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,11 @@ void *threaded_codegen_file(void *parm) {
return NULL;
}

#ifdef NO_THREADS
// no difference.
#define nothread_codegen_file threaded_codegen_file
#endif

void print_json_to_screen(char* output, int count, int done) {
// Print a json block depending on how many there are and where we are.
if(done==1 && count>1) {
Expand All @@ -186,23 +191,13 @@ char *make_json_string(codegen_response_t* response) {
return response->error;
}

// Get the ID3 tag information.
auto_ptr<Metadata> pMetadata(new Metadata(response->filename));

// preamble + codelen
char* output = (char*) malloc(sizeof(char)*(16384 + strlen(response->codegen->getCodeString().c_str()) ));

sprintf(output,"{\"metadata\":{\"artist\":\"%s\", \"release\":\"%s\", \"title\":\"%s\", \"genre\":\"%s\", \"bitrate\":%d,"
"\"sample_rate\":%d, \"duration\":%d, \"filename\":\"%s\", \"samples_decoded\":%d, \"given_duration\":%d,"
sprintf(output,"{\"metadata\":{\"artist\":\"\", \"release\":\"\", \"title\":\"\", \"genre\":\"\", \"bitrate\":0,"
"\"sample_rate\":0, \"duration\":0, \"filename\":\"%s\", \"samples_decoded\":%d, \"given_duration\":%d,"
" \"start_offset\":%d, \"version\":%2.2f, \"codegen_time\":%2.6f, \"decode_time\":%2.6f}, \"code_count\":%d,"
" \"code\":\"%s\", \"tag\":%d}",
escape(pMetadata->Artist()).c_str(),
escape(pMetadata->Album()).c_str(),
escape(pMetadata->Title()).c_str(),
escape(pMetadata->Genre()).c_str(),
pMetadata->Bitrate(),
pMetadata->SampleRate(),
pMetadata->Seconds(),
escape(response->filename).c_str(),
response->numSamples,
response->duration,
Expand Down Expand Up @@ -272,10 +267,12 @@ int main(int argc, char** argv) {
if (num_threads < 2) num_threads = 2;
if (num_threads > count) num_threads = count;

thread_parm_t **parm = (thread_parm_t**)malloc(sizeof(thread_parm_t*)*num_threads);
#ifndef NO_THREADS
// Setup threading
pthread_t *t = (pthread_t*)malloc(sizeof(pthread_t)*num_threads);
thread_parm_t **parm = (thread_parm_t**)malloc(sizeof(thread_parm_t*)*num_threads);
pthread_attr_t *attr = (pthread_attr_t*)malloc(sizeof(pthread_attr_t)*num_threads);
#endif

// Kick off the first N threads
int still_left = count-1-already;
Expand All @@ -287,19 +284,27 @@ int main(int argc, char** argv) {
parm[i]->duration = duration;
parm[i]->done = 0;
still_left--;
#ifndef NO_THREADS
pthread_attr_init(&attr[i]);
pthread_attr_setdetachstate(&attr[i], PTHREAD_CREATE_DETACHED);
// Kick off the thread
if (pthread_create(&t[i], &attr[i], threaded_codegen_file, (void*)parm[i]))
throw std::runtime_error("Problem creating thread\n");
#else
// run sequentially, one by one
nothread_codegen_file((void*)parm[i]);
#endif
}

int done = 0;
// Now wait for the threads to come back, and also kick off new ones
while(done<count) {
// Check which threads are done
// -- this is an inefficient polling. Please consider using
// mutex and condvar instead of this "lockfree" algorithm
for(int i=0;i<num_threads;i++) {
if (parm[i]->done) {
if (parm[i]->done) { // There is a race condition here in the threaded version.
// We get a coredump file every hour.
parm[i]->done = 0;
done++;
codegen_response_t *response = (codegen_response_t*)parm[i]->response;
Expand All @@ -315,10 +320,13 @@ int main(int argc, char** argv) {
parm[i]->tag = still_left;
parm[i]->filename = (char*)files[still_left].c_str();
still_left--;
#ifndef NO_THREADS
int err= pthread_create(&t[i], &attr[i], threaded_codegen_file, (void*)parm[i]);
if(err)
throw std::runtime_error("Problem creating thread\n");

#else
nothread_codegen_file((void*)parm[i]);
#endif
}
}
}
Expand All @@ -328,9 +336,11 @@ int main(int argc, char** argv) {
for(int i=0;i<num_threads;i++) {
free(parm[i]);
}
#ifndef NO_THREADS
free(t);
free(parm);
free(attr);
#endif
free(parm);
return 0;

#endif // _WIN32
Expand Down