Code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void Usage(char prog_name[]);
void Gen_data(void *p);
void Gen_bins(void *p);
int Which_bin(void *p);
void Print_histo(void *p);
void func(void *p);
struct test
{
int bin_count, i, bin;
float min_meas, max_meas;
float* bin_maxes;
int* bin_counts;
int data_count;
float* data;
};
typedef struct test struct1;
int main(int argc, char* argv[])
{
struct1 *p;
pthread_t th1, th2, th3;
if (argc != 5)
Usage(argv[0]);
p->bin_count = strtol(argv[1], NULL, 10);
p->min_meas = strtof(argv[2], NULL);
p->max_meas = strtof(argv[3], NULL);
p->data_count = strtol(argv[4], NULL, 10);
p->bin_maxes = malloc(p->bin_count*sizeof(float));
p->bin_counts = malloc(p->bin_count*sizeof(int));
p->data = malloc(p->data_count*sizeof(float));
p=(struct1 *)malloc(sizeof(struct1));
pthread_create(&th1,NULL,(void*) Gen_data,(void*) p);
pthread_create(&th2,NULL,(void*) Gen_bins,(void*) p);
pthread_create(&th3,NULL,(void*) func,(void*) p);
pthread_join(th1,NULL);
pthread_join(th2,NULL);
pthread_join(th3,NULL);
Print_histo(p);
free(p->data);
free(p->bin_maxes);
free(p->bin_counts);
return 0;
} /* main */
void func(void *p)
{
int i;
struct1 *args;
args=(struct1*)p;
for (i = 0; i < args->data_count; i++)
{
args->bin = Which_bin(args);
args->bin_counts[args->bin]++;
}
# ifdef DEBUG
printf("bin_counts = ");
for (i = 0; i < args->bin_count; i++)
printf("%d ", args->bin_counts[i]);
printf("\n");
# endif
}
/*---------------------------------------------------------------------
* Function: Usage
* Purpose: Print a message showing how to run program and quit
* In arg: prog_name: the name of the program from the command line
*/
void Usage(char prog_name[] /* in */)
{
fprintf(stderr, "usage: %s ", prog_name);
fprintf(stderr, "<bin_count> <min_meas> <max_meas> <data_count>\n");
exit(0);
} /* Usage */
/*---------------------------------------------------------------------
* Function: Gen_data
* Purpose: Generate random floats in the range min_meas <= x < max_meas
* In args: min_meas: the minimum possible value for the data
* max_meas: the maximum possible value for the data
* data_count: the number of measurements
* Out arg: data: the actual measurements
*/
void Gen_data(void *p)
{
struct1 *args;
args=(struct1*)p;
int i;
srandom(0);
for (i = 0; i < args->data_count; i++)
args->data[i] = args->min_meas + (args->max_meas - args->min_meas)*random()/((double) RAND_MAX);
#ifdef DEBUG
printf("data = ");
for (i = 0; i < args->data_count; i++)
printf("%4.3f ", args->data[i]);
printf("\n");
#endif
} /* Gen_data */
/*---------------------------------------------------------------------
* Function: Gen_bins
* Purpose: Compute max value for each bin, and store 0 as the
* number of values in each bin
* In args: min_meas: the minimum possible measurement
* max_meas: the maximum possible measurement
* bin_count: the number of bins
* Out args: bin_maxes: the maximum possible value for each bin
* bin_counts: the number of data values in each bin
*/
void Gen_bins(void* p)
{
struct1 *args;
args=(struct1*)p;
float bin_width;
int i;
bin_width = (args->max_meas - args->min_meas)/args->bin_count;
for (i = 0; i < args->bin_count; i++)
{
args->bin_maxes[i] = args->min_meas + (i+1)*bin_width;
args->bin_counts[i] = 0;
}
# ifdef DEBUG
printf("bin_maxes = ");
for (i = 0; i < args->bin_count; i++)
printf("%4.3f ", args->bin_maxes[i]);
printf("\n");
# endif
}
/* Gen_bins */
/*---------------------------------------------------------------------
* Function: Which_bin
* Purpose: Use binary search to determine which bin a measurement
* belongs to
* In args: data: the current measurement
* bin_maxes: list of max bin values
* bin_count: number of bins
* min_meas: the minimum possible measurement
* Return: the number of the bin to which data belongs
* Notes:
* 1. The bin to which data belongs satisfies
*
* bin_maxes[i-1] <= data < bin_maxes[i]
*
* where, bin_maxes[-1] = min_meas
* 2. If the search fails, the function prints a message and exits
*/
int Which_bin(void* p)
{
struct1 *args;
args=(struct1*)p;
int bottom = 0, top = args->bin_count-1;
int mid;
float bin_max, bin_min;
while (bottom <= top)
{
mid = (bottom + top)/2;
bin_max = args->bin_maxes[mid];
bin_min = (mid == 0) ? args->min_meas: args->bin_maxes[mid-1];
if (*(args->data) >= bin_max)
bottom = mid+1;
else if (*(args->data) < bin_min)
top = mid-1;
else
return mid;
}
fprintf(stderr, "Data = %f doesn't belong to a bin!\n", args->data);
fprintf(stderr, "Quitting\n");
exit(-1);
}
/* Which_bin */
/*---------------------------------------------------------------------
* Function: Print_histo
* Purpose: Print a histogram. The number of elements in each
* bin is shown by an array of X's.
* In args: bin_maxes: the max value for each bin
* bin_counts: the number of elements in each bin
* bin_count: the number of bins
* min_meas: the minimum possible measurment
*/
void Print_histo(void *p)
{
struct1 *args;
args=(struct1*)p;
int i, j;
float bin_max, bin_min;
for (i = 0; i < args->bin_count; i++)
{
bin_max = args->bin_maxes[i];
bin_min = (i == 0) ? args->min_meas: args->bin_maxes[i-1];
printf("%.3f-%.3f:\t", bin_min, bin_max);
for (j = 0; j < args->bin_counts[i]; j++)
printf("X");
printf("\n");
}
}
/* Print_histo */