This repository has been archived on 2025-04-11. You can view files and clone it, but cannot push or open issues or pull requests.
csce313-mp4pinie64backup/simpleclient.cpp

311 lines
8.5 KiB
C++
Raw Permalink Normal View History

2015-11-11 17:17:14 -06:00
/*
File: simpleclient.C
Author: R. Bettati
Department of Computer Science
Texas A&M University
Date : 2013/01/31
Simple client main program for MP3 in CSCE 313
*/
/*--------------------------------------------------------------------------*/
/* DEFINES */
/*--------------------------------------------------------------------------*/
/* -- (none) -- */
/*--------------------------------------------------------------------------*/
/* INCLUDES */
/*--------------------------------------------------------------------------*/
#include <cassert>
#include <cstring>
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
2015-11-13 10:02:10 -06:00
#include <sys/time.h>
2015-11-11 17:17:14 -06:00
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include "reqchannel.h"
#include "semaphore.h"
#include "BoundedBuffer.h"
using namespace std;
/*--------------------------------------------------------------------------*/
/* DATA STRUCTURES */
/*--------------------------------------------------------------------------*/
/* none */
/*--------------------------------------------------------------------------*/
/* CONSTANTS */
/*--------------------------------------------------------------------------*/
BoundedBuffer Request_Buffer;
BoundedBuffer Response_Buffer[3];
BoundedBuffer RB1;
2015-11-13 10:02:10 -06:00
struct stat_struct {
vector<int>* statt;
int tid;
};
2015-11-11 17:17:14 -06:00
2015-11-13 10:02:10 -06:00
int n = 1000, b = 100, w = 5, c = 0;//set defaults
Semaphore mutex(1);
2015-11-11 17:17:14 -06:00
/*--------------------------------------------------------------------------*/
/* FORWARDS */
/*--------------------------------------------------------------------------*/
void* Req_Thread(void* args);
void* Worker_Thread(void* args);
void* Stat_Thread(void* args);
2015-11-13 10:02:10 -06:00
long get_time_diff(struct timeval *start, struct timeval *end);
2015-11-11 17:17:14 -06:00
/*--------------------------------------------------------------------------*/
/* MAIN FUNCTION */
/*--------------------------------------------------------------------------*/
int main(int argc, char * argv[]) {
int option = -1;
while ((option = getopt(argc, argv, "n:b:w:")) != -1){
switch (option){
case 'n' :
n = atoi(optarg);
break;
case 'b' :
b = atoi(optarg);
break;
case 'w' :
w = atoi(optarg);
break;
}
}
2015-11-13 10:02:10 -06:00
//cout << "n: " << n << "b: " << b << "w: " << w << "\n\n";
2015-11-11 17:17:14 -06:00
pid_t pid = fork();
2015-11-13 10:02:10 -06:00
if(pid == 0){
2015-11-11 17:17:14 -06:00
2015-11-13 10:02:10 -06:00
struct timeval tp_start;
struct timeval tp_end;
long time_diff;
assert(gettimeofday(&tp_start, 0) == 0);
2015-11-11 17:17:14 -06:00
Request_Buffer.set_empty(b);
2015-11-13 10:02:10 -06:00
Response_Buffer[0].set_empty(n);
Response_Buffer[1].set_empty(n);
Response_Buffer[2].set_empty(n);
vector<int> John_vec(100);
stat_struct John_struct;
John_struct.statt = &John_vec;
John_struct.tid = 0;
vector<int> Jane_vec(100);
stat_struct Jane_struct;
Jane_struct.statt = &Jane_vec;
Jane_struct.tid = 1;
vector<int> Joe_vec(100);
stat_struct Joe_struct;
Joe_struct.statt = &Joe_vec;
Joe_struct.tid = 2;
2015-11-11 17:17:14 -06:00
RequestChannel chan("control", RequestChannel::CLIENT_SIDE);
pthread_t request_thread_ids[3];
pthread_t worker_thread_ids[w];
pthread_t statistic_thread_ids[3];
RequestChannel* worker_return[w];
//---------------------------------------------
//------- pthread_create -------
//---------------------------------------------
int index[3];
for(int i=0; i < 3; i++){
index[i] = i;
pthread_create(&request_thread_ids[i], NULL, Req_Thread, (void *)&index[i]);
}
for(int i=0; i < w; i++){
string channel_name = chan.send_request("newthread");
worker_return[i] = new RequestChannel(channel_name, RequestChannel::CLIENT_SIDE);
pthread_create(&worker_thread_ids[i], NULL, Worker_Thread, worker_return[i]);
}
2015-11-13 10:02:10 -06:00
//
2015-11-11 17:17:14 -06:00
for(int i=0; i < 3; i++){
2015-11-13 10:02:10 -06:00
if(i == 0) {
pthread_create(&statistic_thread_ids[i], NULL, Stat_Thread, (void *)&John_struct);
}
else if(i == 1) {
pthread_create(&statistic_thread_ids[i], NULL, Stat_Thread, (void *)&Jane_struct);
}
else if(i == 2) {
pthread_create(&statistic_thread_ids[i], NULL, Stat_Thread, (void *)&Joe_struct);
}
2015-11-11 17:17:14 -06:00
}
2015-11-13 10:02:10 -06:00
//
2015-11-11 17:17:14 -06:00
//---------------------------------------------
//-------- pthread_join --------
//---------------------------------------------
for(int i=0; i < 3; i++){
pthread_join(request_thread_ids[i], NULL);
}
for(int i=0; i < w; i++){
pthread_join(worker_thread_ids[i], NULL);
}
2015-11-13 10:02:10 -06:00
//
2015-11-11 17:17:14 -06:00
for(int i=0; i < 3; i++){
pthread_join(statistic_thread_ids[i], NULL);
}
2015-11-13 10:02:10 -06:00
//
assert(gettimeofday(&tp_end, 0) == 0);
2015-11-11 17:17:14 -06:00
for(int i=0; i < w; i++){
worker_return[i]->send_request("quit");
}
2015-11-13 10:02:10 -06:00
cout << "\n\n JOHN HISTOGRAM\n";
//int ct = 0;
2015-11-11 17:17:14 -06:00
for(int i=0; i < 100; i++){
2015-11-13 10:02:10 -06:00
//
cout << "Num[" << i << "]: ";
for(int j=0; j < John_vec[i]; j++) {
cout << "*";
}
//
//cout << John_vec[i];
cout << "\n";
}
cout << "\n\n JANE HISTOGRAM\n";
//int ct = 0;
for(int i=0; i < 100; i++){
//
cout << "Num[" << i << "]: ";
for(int j=0; j < Jane_vec[i]; j++) {
cout << "*";
}
//
//cout << Jane_vec[i];
cout << "\n";
}
cout << "\n\n JOE HISTOGRAM\n";
//int ct = 0;
for(int i=0; i < 100; i++){
//
cout << "Num[" << i << "]: ";
for(int j=0; j < Joe_vec[i]; j++) {
cout << "*";
}
//
//cout << Joe_vec[i];
cout << "\n";
2015-11-11 17:17:14 -06:00
}
//STILL NEED TO OUTPUT THE HISTOGRAM SOMEHOW....
chan.send_request("quit");
2015-11-13 10:02:10 -06:00
time_diff = get_time_diff(&tp_start, &tp_end);
cout << "time_diff: " << time_diff << "musec, " << (time_diff/1000000) << "sec" << endl;
2015-11-11 17:17:14 -06:00
}else{
execl("dataserver", 0);
}
usleep(1000000);
}
void* Worker_Thread(void* arg){
RequestChannel* chann = (RequestChannel*)arg;
2015-11-13 10:02:10 -06:00
string request;
2015-11-11 17:17:14 -06:00
while(true){
2015-11-13 10:02:10 -06:00
mutex.P();
if(!Request_Buffer.is_empty()) {
request = Request_Buffer.pop();
c++;
}
else if(c < (3*n)){
mutex.V();
continue;
}
else {
mutex.V();
break;
}
mutex.V();
2015-11-11 17:17:14 -06:00
string response = chann->send_request(request);
2015-11-13 10:02:10 -06:00
//cout << "\nc: " << c << "\n\n";
2015-11-11 17:17:14 -06:00
if(request == "data Joe Smith"){
Response_Buffer[0].push(response);
}else if(request == "data Jane Smith"){
Response_Buffer[1].push(response);
}else if(request == "data John Doe"){
Response_Buffer[2].push(response);
}
}
}
void* Req_Thread(void* arg){
int person = *(int*)arg;
2015-11-13 10:02:10 -06:00
//cout << "PERSON: " << person << endl;
2015-11-11 17:17:14 -06:00
switch(person){
case 0:
2015-11-13 10:02:10 -06:00
for(int i=0; i < n; i++){ Request_Buffer.push("data Joe Smith"); }
2015-11-11 17:17:14 -06:00
break;
case 1:
2015-11-13 10:02:10 -06:00
for(int i=0; i < n; i++){ Request_Buffer.push("data Jane Smith"); }
2015-11-11 17:17:14 -06:00
break;
case 2:
2015-11-13 10:02:10 -06:00
for(int i=0; i < n; i++){ Request_Buffer.push("data John Doe"); }
2015-11-11 17:17:14 -06:00
break;
}
}
void* Stat_Thread(void* arg){
//send to proper response buffer based on which name is found!
2015-11-13 10:02:10 -06:00
stat_struct &sts = *(stat_struct*)arg;
vector<int> *stat_vec = sts.statt;
int person = sts.tid;
2015-11-11 17:17:14 -06:00
string num;
2015-11-13 10:02:10 -06:00
for(int i=0; i < n; i++){
num = Response_Buffer[person].pop();
//cout << "\nPERSON0: " << num << endl;
int v = atoi(num.c_str());
(*stat_vec)[v] = (*stat_vec)[v] + 1;
2015-11-11 17:17:14 -06:00
}
}
2015-11-13 10:02:10 -06:00
long get_time_diff(struct timeval * tp1, struct timeval * tp2) {
/* Prints to stdout the difference, in seconds and museconds, between two
timevals. */
//long sec = tp2->tv_sec - tp1->tv_sec;
long musec = tp2->tv_usec - tp1->tv_usec;
if (musec < 0) {
musec += 1000000;
}
return musec;
}
2015-11-11 17:17:14 -06:00