0

I am compiling some source that is linked to two packages. One is OpenCV and the other is a driver library for an infrared camera. The company only provides a 32-bit version of the library via an rpm package. I compiled OpenCV from source and it's libraries are installed in /usr/local/lib64. I am running Fedora 18 64-bit version. Here is my CMakeLists.txt:

CMAKE_MINIMUM_REQUIRED(VERSION 2.6) 
PROJECT(xeneth_test) 

SET(CMAKE_MODULE_PATH ${CMAKE_MODULES_PATH} /home/sam/Documents/common/CMakeModules) 
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) 
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) 
SET(CMAKE_CXX_FLAGS "-m32") 

FIND_PACKAGE(Xeneth REQUIRED) 
INCLUDE_DIRECTORIES(${LIBXENETH_INCLUDE_DIRS}) 

FIND_PACKAGE(OpenCV REQUIRED) 

#GENERATE EXECUTABLES 
ADD_EXECUTABLE(myXenethTest src/myXenethTest.cpp) 
TARGET_LINK_LIBRARIES(myXenethTest ${XENETH_LIBRARIES} ${OpenCV_LIBS})

When I run make I get:

Scanning dependencies of target myXenethTest
[100%] Building CXX object CMakeFiles/myXenethTest.dir/src/myXenethTest.cpp.o
Linking CXX executable bin/myXenethTest
/usr/local/lib64/libopencv_calib3d.so: could not read symbols: File in wrong format
collect2: error: ld returned 1 exit status
make[2]: [bin/myXenethTest] Error 1
make[1]:
[CMakeFiles/myXenethTest.dir/all] Error 2
make: *** [all] Error 2

This is probably because I am trying to link my target against a 64-bit compiled OpenCV and the 32-bit Xeneth libraries. I have to inlude the -m32 compiler flag, otherwise the libxeneth library won't be used. I just started recently with this whole 64-bit computing and after some time trying to find a solution, I am quite lost. Looking forward to any input/suggestions/answers to my problem. Thanks for your time.

-Sam

0

I recently received a new 64-bit laptop and is my first endeavor into 64-bit computing. I installed all my usual packages through yum (I am using fedora 64 bit) and it downloaded all the 64-bit versions of the packages. I went to install an rpm packaged by years ago by a colleague at my university and the installer notified me that I had to install the 32-bit versions of about 40 dependencies (the dependencies of the dependencies as well). Now I have a lot of questions and can't find the answers. I would appreciate some feedback on my two largest questions:

1a - If I have both versions of a library, say libABC.x86_64 and libABC.i686 (the 64 and 32 bit versions of libABC) how does the compiler (I always use cmake) know to use the 64 or 32 bit version?

1b - If I install the 32 and 64 bit versions of all the packages and compilers, do I now have to specify which compilers I use?

2 - I had installed OpenCV yesterday (downloading all the 64-bit dependicies prior) via the git source code. Now I was curious to see if OpenCV had installed its libraries into /usr/local/lib or /usr/local/lib64. It installed in /usr/local/lib. What's the deal? This code was compiled using 64-bit dependecny libraries using 64-bit compilers (all located in /usr/lib64) and it installed it's libraries into a 32-bit directory. Am I supposed to specify otherwise?

Thatnks for your time, looking forward to any feedback you can give. ...

0

Thanks for the reply. I actually had thought of this, but it still requires a listing of all the functions (in the array initialization). I don't want to make it seem like I am being lazy, just curious really. I was wondering if there was some trickery that I didn't know of that could be even more direct. Using the ID to directly call the function. It turns out that some ID's are totaly different from the others. The list is like 1, 2, 3, 7, 14, 15, 20, 21, 22, 10001, 1007, 10008. The method you suggest would actually need a hash table. Probably best to just use a switch or else/if sequence. Not unless there is some other trickery.

-Sam

0

I am writting a driver for a GPS unit in linux. I can set on the GPS unit what data it should send out it's ethernet port. The data is arranged in structs of different sizes depending on what it is. For example one packet could be for the GPS solution (containing position, velocity, and orientation data). Another packet could be error information. Regardless, each packet starts with a unique ID. So what I want to do is abitrarily read in all packets from the unit and parse them as they come in depending on the packets unique ID. I am not sure how to do this elegantly though. I don't want to do a switch or else if sequence. So:

if(packet_id == 1)
  parse_gps_solution(packet_data); //function call that parses the data into the correct struct
else if(packet_id == 2)
  parse_gps_error(packet_data);
else if(packet_id == 3)
  parse_raw_gps(packet_data);
etc...

This is not what I want. I am trying to see if there is a way I can elegantly parse using the packet ID itself, I am just not sure how I could do this. I would appreciate any and all brain storming suggestions. Any questions, please ask. Thank you.

-Sam

0

I am trying to change assign the pointer "c" to the pointer "a" below using the function "change()", but I am doing something incorrectly, not exactly sure. The direct assignment within the main() function works (ie a = c), but does not work using the change function.

[CODE]
void change(float (d)[3], float (e)[3]){
d = e;
}

main(){
float (a)[3], (b)[3], c[3][3];
int i, j;
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
c[i][j] = 5;
}
}

//a = c
change(a, c);

for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
cout << a[i][j] << " ";
}
cout << endl;
}

return 0;
}[/CODE]

Thanks.

-Sam

0

I know how the command line arguments work. That is not my question. I have to make the line [CODE]QApplication application(argc, argv);[/CODE] global. In order to do so I have to make two arguments. As stated in my original post, I do not know how I can set a string to a double char pointer.

chrjs,
So I already tried that. That was actually one of the first things I thought of. So as I was typing this response to you, on a hunch, I decided to try it again. I made a global Viewer view, then set that equal to &viewer in main(), then in my function call I used (view).updateGL(); and I was getting an error when I executed the function. Well the function was this:

[CODE]
void on_trackbar(int h){
(*view).updateGL();
}
[/CODE]

on_trackbar(int h) is an openCV function that is called whenever the trackbar is moved. Turns out when I initialize the trackbar (which was in main(), before the view = &viewer) OpenCV calls this on_trackbar() function. So that's where the problem was. The (*view).updateGL() function was being called in on_trackbar() without me knowing. So I put view = &viewer; before the trackbar initialization and everything worked. Thanks, without your post I would have never tried that again.

0

Hi everyone, I am working on a 3D viewer using libQGLViewer. In all of the examples provided, the main function looks something like this:
[CODE]
int main(int argc, char** argv){
QApplication application(argc, argv);
Viewer viewer;

if QT_VERSION < 0x040000

application.setMainWidget(&viewer);

else

viewer.setWindowTitle("pointCloud");

endif

viewer.show();

return(g_qApplication.exec()); //waits for Esc
}
[/CODE]

The application and viewer objects need only be referenced in the main loop for all of the examples provided, but for my program, I need to call a function viewer.updateGL() that exists outside the main loop. So I made viewer global. This was not OK, QApplication complained because it needs to be constructed before the Viewer. So I made QApplication application(argc, argv); global with both arguments NULL because I don't use them. QT complained and said it needs real arguments, specifically, the first argument cannot be zero and the second must contain atleast one argument. Problem is, I have no idea how to set a string in a double pointer char (ie. char **argv). I just wasted a lot of time trying to find out and didn't come up with anything. Anyone have any ideas? I basically want this: argv[0] = "./PointCloud", where argv[0][0] to argv[0][12] would contain all the letters and a NULL terminator at the end. There has to be a simple way to do this. Thanks.

0

read_into_array(input, vals, 100);
print_above_avg(vals, 100);

You can't call print_above_avg putting 100 in because you do not know (I am assuming) that there is in fact 100 numbers in the file. The value you give to this function needs to be a number returned from your file read that specifies how many integers were read. As for the second question, you are correct. Iterate through the values read back from file and check to see if a particular value is greater than the returned average, if it is, print it out. Good luck.

-Sam

0

Yeah sorry about not using the code blocks tags, my first post, didn't know. I am still in wonder why this is not working. I spent hours trying to figure out why the last thread is getting stopped while trying to unlock the condition mutex. As for not using the predicates for starting and stopping vThread(), you got me there, should be using a predicate as I am with nCount. As for the spurious wake-ups, I had tried both if(nCount < 4) and while(nCount < 4) and both times I was still getting hung up on that last thread try to leave the condition mutex after is signals. So it isn't a spurious wake-up problem. I took a look at the boost stuff, looks like it is very easy and intuitive, but something about me has to figure this one out. Many thanks for the reply.

threads...

-1

[QUOTE]

  1. You should only calculate your average after you have accumulated the total sum. Move this Line: avg = sum / vals[i] to a line after the end of your loop.
    [QUOTE]

avg = sum / vals[i]... you sure about that?

[CODE]
//int num_elem......number of elements present in vals[]
void print_above_avg(int vals[], int num_elem)
{
double avg, sum=0; //sum should be declared double

    //for(int i=0; i<vals[i]; i++) wrong
for(int i=0; i<num_elem; i++)
{
    sum += vals[i];
    cout << vals[i] << endl;
    //avg = sum / vals[i]; wrong
}
    avg = sum/(double)num_elem;
cout << "The total is " << sum << endl;
cout << "The avg is " << avg << endl;

}[/CODE]

Votes + Comments
Read the rules, don't just give away code. :(
0

[CODE]#include <iostream>

include <string>

using namespace std;

const int SIZE=30;
const int bSIZE=3;
void Initialize(struct Book*arrbook [], int size);

struct Book{
string title; string author;
Book(string t, string a):title(t),author(a) {}
};

int main(){
int choice1, choice2;
string title, author;

Book *arrbook[bSIZE];
Initialize(arrbook,bSIZE);

do{
cout<< "Enter 1 to View, or 2 to Modify, or 3 to Quit: ";
cin >> choice1;

switch (choice1){
  case 1:
    for (int i = 0; i < 3; i++){
  cout << "Title " << (i+1) << " is :" << arrbook[i]-> title << endl;
  cout << "Author " << (i+1) << " is :" << arrbook[i]-> author << endl;
    }           

//} BAD BRACKET
break;

  case 2:
    cout << "Enter which book to modify: " << endl;
cin >> choice2;
    if(choice2 > 3)
      cout << "Must be a book 1 through 3" << endl;
else{
  cout << "Enter the title: ";
  cin >> title;
  arrbook[choice2 - 1]->title = title; //same as *(arrbook[choice2 - 1]).title = title;
  cout<< "Enter the author: ";
  cin >> author;
  arrbook[choice2 - 1]->author = author; //same as *(arrbook[choice2 - 1]).author = author;
    }
    break;

  case 3:
    break;

  default: 
    cout << "The valid choices are 1 through 3. Run the program again and select one of those." << endl;
}

}while(choice1 != 3);
//system ("pause");
return(0);
}

void Initialize(struct Book*arrbook[], int size){
for(int i = 0; i < size; i++)
arrbook[i]= new Book("None","None");
}[/CODE]

Output:

Enter 1 to View, or 2 to Modify, or 3 to Quit: 2
Enter which book to modify:
1 ...

0

Here is how you should do it:

[CODE]#include <iostream>

include <string>

using namespace std;

const int SIZE = 30;
const int bSIZE = 3;

struct Book{
string title;
string author;
Book(string t, string a):title(t),author(a) {}
};

/'struct Book arrbook[]' is the same thing as 'struct Book *arrbook' /
void Initialize(struct Book *arrbook[], int size){
for(int i = 0; i < size; i++)
arrbook[i] = new Book("None", "None");
}

int main(){
int choice1, choice2;
string title;
string author;

/ This declares an array of pointers to Book structures /
Book *arrbook[bSIZE];

Initialize(arrbook, bSIZE);

system ("pause");
return 0;
}

/ Here is a different way to do the same thing but it looks better /

void Initialize_NEW(struct Book *arrbook, int size){
arrbook = NULL;
arrbook = new Book
[size];
for(int i = 0; i < size; i++)
arrbook[i] = new Book("None", "None");
}

int main_NEW(){
int choice1, choice2;
string title;
string author;

Book **arrbook;

Initialize(arrbook, bSIZE);

system ("pause");
return 0;
}[/CODE]

-Sam

0

On a hunch I decided to find out how to read numbers from a text file, as that is something I never had to do before. This reads data.txt in two different ways and prints the largest odd number. Usually you write data to files from a program and it is saved as a non-readable text file that you can just read directly back into an array, which is easier to do than read from a text formated file.

-Sam

[CODE]#include <iostream>

include <fstream>

include <sstream>

define FILE_LOC "/home/sam/Desktop/data.txt"

using namespace std;

//assuming largest was set to zero
void largestOdd(int *B, int sizeB, int& largest){
for(int i = 0; i < sizeB; i++)
if( ( (B[i] % 2) == 1) && (B[i] > largest) )
largest = B[i];
}

int nReadFile1(int *Array){
ifstream fin(FILE_LOC);
string line;
int val, i = 0;

while( getline(fin, line) ) {
//cout << line << endl;
istringstream tokenizer(line);
string token;

//this line removes the values seperated by cariage returns
getline(tokenizer, token, (char)(13) );
istringstream int_iss(token);
int_iss >> val;
printf("%d\n", val);
Array[i] = val;
i++;

}

return(i);
}

int nReadFile2(int *Array) {
int i = 0, val;
ifstream inFile;

inFile.open(FILE_LOC, ifstream::in);
if(!inFile){
printf("File open error\n");
return(-1);
}

while (inFile >> val) {
printf("%d\n", val);
Array[i] = val;
i++;
}

inFile.close();
return(i);
}

int main(){
int x[50]; //array to hold 50 elements
int Size, Largest = 0;

//Size = nReadFile1(x);
Size = nReadFile2(x);

printf("\nFile contained %d integers\n", Size);

largestOdd(x, Size, Largest); //function call

printf("\nThe largest odd number ...

0

ok, so I can't run your program as I thought because I do not have the header conio.h in linux. This is a simple problem though. You need to as I mentioned earlier make sure that you are reading the values in from your file correctly by first reading them in and then printing them out. Then you have file reading basics down. Once that is solved, if it needed solving, then just use the function I gave you.

void largestOdd(int *B, int sizeB, int& largest)

So your code would look like:

[CODE]

void largestOdd(int *B, int sizeB, int& largest){
for(int i = 0; i < sizeB; i++)
if( ( (B[i] % 2) == 1) && (B[i] > largest) )
largest = B[i];
}

int main()
{
ins.open(in_file); //open file
int x[50]; //array to hold 50 elements
const int Size = 50;
int Largest = 0;

readValues(x,Size); //function call

largestOdd(x, 50, Largest); //function call

cout << "\nThe largest odd number is: " << Largest;

getch();
ins.close();
return(0);
}

void readValues(int A[], int sizeA)
{
char next_char;
int i = 0;

for(;;)
{
    if (ins.eof() || i>=sizeA) //check end of file
        break;
    ins >> A[i];
    cout << A[i] << endl; //echo print input data
    ins.get(next_char); //skipping end-of-line char
    i++;
}
return;

}

[/CODE]

-Sam

0

[QUOTE=hq1;1390330]Hi so I have this program to find the largest odd number from an array of 50, the program runs fine, but the problem is after reading the numbers from file it says the largest odd number is 0. Can some one please have a look for me and tell me where my mistake is. ITS DRIVING ME INSANE haha!

[CODE]//File: lab8a.cpp
/Purpose: to find the largest odd number in a 50-element
array of integers.
/

include <iostream>

include <fstream>

include <conio.h>

define in_file "data.txt"

using namespace std;

ifstream ins; //ins as input stream

void readValues(int[],int); //input values into array
void largestOdd(int[],int&); //find largest odd number

void main()
{
ins.open(in_file); //open file
int x[50]; //array to hold 50 elements
const int Size = 50;
int Largest = 0;

readValues(x,Size); //function call
largestOdd(x,Largest); //function call

cout << "\nThe largest odd number is: " << Largest;

getch();
ins.close();
}

void readValues(int A[], int sizeA)
{
char next_char;
int i = 0;

for(;;)
{
    if (ins.eof() || i>=sizeA) //check end of file
        break;
    ins >> A[i];
    cout << A[i] << endl; //echo print input data
    ins.get(next_char); //skipping end-of-line char
    i++;
}
return;

}

void largestOdd(int B[50], int& largest)
{
int i = 0;

ins >> B[i];
while(!ins.eof())
{
    if(B[i] % 2 == 1)
    {
        if(B[i] > B[i+1])
        {
            largest = B[i];
            B[i] = B[i+1];
            B[i+1] = largest;
        }
    }
    i++;
}

}[/CODE][/QUOTE]

I didn't really bother trying to debug the above. I would make sure that you are reading in your values correctly from ...

1

Hello,

I have 2D matrix with greyscale image data, in particular point I have computed vector, which contains gradient in this point (via Sobel operator, it has 2 values - difference in x and in y axis), and I store this gradient vector like perpendicular vector to this gradient, so I have the vector, which says me the orientation of the edge in this point.

Now, what I want - I want to draw orientation of this edge in that particular point in my 2D image matrix like small line (for example 10 pixels) and I want to draw it in the way of this vector I have computed.

Any idea, how to do that?

Thanks for any help!

Well I am not exactly sure what you are trying to do, but i have worked with the sobel operator before in an edge detector. Assuming you know how to apply the x and y sobel operators to get the x and y gradient values (here they are Gx and Gy) then you can calculate the direction (theta) and magnitude of the gradient at every point. Here is a code snippet:

  /* Two theta condtions, need manual setting */
  if(Gx == 0){
    if(Gy == 0) //if Gx and Gy are zero, theta is zero
      theta = 0;
    else 
      theta = 90; // Gx is zero and Gy is non-zero, theta is 90
  }
  /* if not condition, calculate actual edge direction */ ...
0

I am working on some image processing ideas and I want to implement them using pthreads. Here is an example I came up with just to make sure that the threads were actually doing what they were supposed to be doing. It just increments the values in an array and prints the run time. There is also a serial version of the incrementing function just to show the benefits of the pthreads. The program is getting hung up though and I am not sure why or how to fix this. It is labeled in two locations (same error) as "FOO". The code runs correctly but not without the two usleep(1000) inserted in nIncreaseArray() (both marked with "FOO"). Let me know what you think and if you have any suggestions, thanks. The code is also attached as a .cpp if you want to compile and run.

Sam

//pthread_example1.cpp.cpp

#include <iostream>
#include <stdio.h> //used for printf
#include <math.h>
#include <errno.h>
#include <sys/time.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>

using namespace std;

#define ARRAY_HEIGHT 50 //each cell represents a ditsance of 5cm
#define ARRAY_WIDTH 50 //each cell represents a ditsance of 5cm

int g_anArray[ARRAY_HEIGHT][ARRAY_WIDTH];

pthread_mutex_t mutex[4], count_cond_mutex, count_mutex;
pthread_cond_t condition[4], count_condition;
pthread_t threads[4];
pthread_attr_t attr;
int nCount = 0;
bool bExit[4];

int nInit(){
  int i, nError;

  /* Initialize mutex and condition variable objects */
  for(i = 0; i < 4; i++){
    pthread_mutex_init(&mutex[i], NULL);
    pthread_cond_init (&condition[i], NULL);
  }
  pthread_mutex_init(&count_cond_mutex, NULL);
  pthread_mutex_init(&count_mutex, NULL);
  pthread_cond_init(&count_condition, NULL);

  /* For portability, explicitly create threads in a joinable state ...
Attachments
//pthread_example1.cpp.cpp


#include <iostream>
#include <stdio.h> //used for printf
#include <math.h>
#include <errno.h>
#include <sys/time.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>

using namespace std;

#define ARRAY_HEIGHT 50 //each cell represents a ditsance of 5cm
#define ARRAY_WIDTH 50 //each cell represents a ditsance of 5cm

int g_anArray[ARRAY_HEIGHT][ARRAY_WIDTH];

pthread_mutex_t mutex[4], count_cond_mutex, count_mutex;
pthread_cond_t condition[4], count_condition;
pthread_t threads[4];
pthread_attr_t attr;
int nCount = 0;
bool bExit[4];


int nInit(){
  int i, nError;

  /* Initialize mutex and condition variable objects */
  for(i = 0; i < 4; i++){
    pthread_mutex_init(&mutex[i], NULL);
    pthread_cond_init (&condition[i], NULL);
  }
  pthread_mutex_init(&count_cond_mutex, NULL);
  pthread_mutex_init(&count_mutex, NULL);
  pthread_cond_init(&count_condition, NULL);

  /* For portability, explicitly create threads in a joinable state */
  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

  memset(bExit, false, 4);

  return(0);
}

int nUninit(){
  /* remove thread dependencies */
  pthread_attr_destroy(&attr);
  pthread_mutex_destroy(&count_cond_mutex);
  pthread_mutex_destroy(&count_mutex);
  pthread_cond_destroy(&count_condition);
  for(int i = 0; i < 4; i++){
    pthread_mutex_destroy(&mutex[i]);
    pthread_cond_destroy(&condition[i]);
  }

  pthread_exit(NULL);
  //return(0);
}


void *vThread(void *pvQuadrant){
  int r_t, r_b, c_l, c_r, x, y, q;

  q = (int)pvQuadrant;
  /* Set index limits for quadrant */
  if(q == 0){
    r_t = 0; r_b = (ARRAY_HEIGHT / 2) - 1; c_l = ARRAY_WIDTH / 2; c_r = ARRAY_WIDTH - 1;
  }
  if(q == 1){
    r_t = 0; r_b = (ARRAY_HEIGHT / 2) - 1; c_l = 0; c_r = (ARRAY_WIDTH / 2) - 1;
  }
  if(q == 2){
    r_t = ARRAY_HEIGHT / 2; r_b = ARRAY_HEIGHT - 1; c_l = 0; c_r = (ARRAY_WIDTH / 2) - 1;
  }
  if(q == 3){
    r_t = ARRAY_HEIGHT / 2; r_b = ARRAY_HEIGHT - 1; c_l = ARRAY_WIDTH / 2; c_r = ARRAY_WIDTH - 1;
  }

  //let calling process know that all the threads have been created
  pthread_mutex_lock(&count_cond_mutex);
    nCount++;
    if (nCount == 4)
      pthread_cond_signal(&count_condition);
  pthread_mutex_unlock(&count_cond_mutex);

  while(true){
    pthread_mutex_lock(&mutex[q]);
    pthread_cond_wait(&condition[q], &mutex[q]);
    pthread_mutex_unlock(&mutex[q]);

    if(bExit[q]){
      printf("Thread %d exited\n", q);
      pthread_exit(NULL);
    }

    //PUT CODE FOR MANIPULATING QUADRANTS OF 2-D ARRAY
    for(y = r_t; y <= r_b; y++){
      for(x = c_l; x <= c_r; x++){
        g_anArray[y][x]++;
      }
    }
    //usleep(500000); //this is just so you can see they all have to finish first

    /* Check if thread is the last one finsihed, if so, signal nIncreaseArray() that vDilate is finsihed */
    pthread_mutex_lock(&count_cond_mutex);
      nCount++;
      if (nCount == 4)
        pthread_cond_signal(&count_condition);
    pthread_mutex_unlock(&count_cond_mutex);

  }
}


int nIncreaseArray(int amount){
  int nError, i, j;
  timeval clk1, clk2; 

  /* Create all the threads for vDilate */
  for(i = 0; i < 4; i++){
    if( nError = (pthread_create(&threads[i], &attr, vThread, (void *)i) != 0) ){
      cout << "Pthread_Example1: nIncreaseArray() - pthread_create() error - " << strerror( nError ) << endl;
      return(-1);
    }
  }
  /* give threads a moment to be created */
  pthread_mutex_lock(&count_cond_mutex);
    if(nCount < 4){ //don't run pthread_cond_wait if nCount already reached 4 because pthread_cond_wait will never receive the signal
      pthread_cond_wait(&count_condition, &count_cond_mutex);
      nCount = 0;
    }
  pthread_mutex_unlock(&count_cond_mutex);
  usleep(1000); //FOO - do work here or last running thread in vThread gets hung up on pthread_mutex_unlock(&count_cond_mutex);

  for(j = 0; j < amount; j++){

    gettimeofday(&clk1, NULL);

    printf("Threads Starting\n");

    /* Signal threads to start */
    for (i = 0; i < 4; i++){
      pthread_mutex_lock(&mutex[i]);
        pthread_cond_signal(&condition[i]);
      pthread_mutex_unlock(&mutex[i]);
    }
    /* Wait for all threads to complete (the last thread will make nCount 4 and call pthread_cond_signal()) */
    pthread_mutex_lock(&count_cond_mutex);
      if(nCount < 4){ //don't run pthread_cond_wait if nCount already reached 4 because pthread_cond_wait will never receive the signal
        pthread_cond_wait(&count_condition, &count_cond_mutex);
        nCount = 0;
      }
    pthread_mutex_unlock(&count_cond_mutex);
    usleep(1000); //FOO - do work here or last running thread in vThread gets hung up on pthread_mutex_unlock(&count_cond_mutex);

    printf("Threads Finished\n");
    gettimeofday(&clk2, NULL);
    printf("Threads Execution Time: %.6f seconds\n\n", (double)(clk2.tv_sec - clk1.tv_sec) + 
           ( ( (double)(clk2.tv_usec - clk1.tv_usec) ) / 1000000 ) );

  }

  /* Terminate all the threads, wait for them to finish */
  memset(bExit, true, 4);
  for(i = 0; i < 4; i++){
    pthread_mutex_lock(&mutex[i]);
    pthread_cond_signal(&condition[i]);
    pthread_mutex_unlock(&mutex[i]);
  }
  for(i = 0; i < 4; i++){
    if(nError = (pthread_join(threads[i], NULL) != 0) ){
      cout << "Pthread_Example1: nIncreaseArray() -  pthread_join() error - " << strerror(nError) << endl;
      return(-1);
    }
  }
}


int nIncreaseArray_s(int amount){
  int x, y, j;
  timeval clk1, clk2;

  printf("Serial Started\n");
  for(j = 0; j < amount; j++){

    gettimeofday(&clk1, NULL);

    /* Signal vDilate threads to start */
    printf("iteration: %d\n", j);
    for(y = 0; y < ARRAY_HEIGHT; y++){
      for(x = 0; x < ARRAY_WIDTH; x++){
        g_anArray[y][x]++;
      }
    }

    //usleep(50000); //this is just so you can see they all have to finish first

    gettimeofday(&clk2, NULL);
    printf("Serial Execution Time: %.6f seconds\n\n", (double)(clk2.tv_sec - clk1.tv_sec) + 
           ( ( (double)(clk2.tv_usec - clk1.tv_usec) ) / 1000000 ) );

  }
  printf("Serial Finsished\n");
}


void vPrintArray(){
  for(int r = 0; r < ARRAY_HEIGHT; r++){
    for(int c = 0; c < ARRAY_WIDTH; c++){
      cout << g_anArray[r][c] << " ";
    }
    cout << endl;
  }
}


int main(int argc, char *argv[]){
  if(nInit() == -1){
    printf("Pthread_Example1: main() - nInit() error\n");
    return(-1);
  }

  //memset(g_anArray, 0, sizeof(g_anArray));
  //nIncreaseArray_s(10);
  memset(g_anArray, 0, sizeof(g_anArray));
  nIncreaseArray(20);
  vPrintArray();

  if(nUninit() == -1){
    printf("Pthread_Example1: main() - nUninit() error\n");
    return(-1);
  }

  pthread_exit(NULL);
}