From 33f554d71463d1b4ab026f78defa74b0df48bfe8 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Mon, 6 Apr 2009 18:38:30 +0000 Subject: [PATCH] reworking distrib & Scene to work together git-svn-id: svn://anubis/fart/trunk@226 7f9b0f55-74a9-4bce-be96-3c2cd072584d --- distrib/distrib.cc | 55 +++++++++++++++++++++++++--- distrib/distrib.h | 13 +++++-- main/Scene.cc | 89 ++++++++++++++++++++++++++++++++++------------ main/Scene.h | 2 ++ main/fart.cc | 8 ++--- 5 files changed, 133 insertions(+), 34 deletions(-) diff --git a/distrib/distrib.cc b/distrib/distrib.cc index e5d6097..3f298aa 100644 --- a/distrib/distrib.cc +++ b/distrib/distrib.cc @@ -6,6 +6,8 @@ #include #include #include +#include /* gethostbyname() */ +#include /* memset() */ #include #include #include @@ -39,15 +41,15 @@ int distrib::readHostFile(const char * filename) int distrib::startClients(const std::vector & client_options) { - int err = 0; + int ret = 0; for (int i = 0, sz = m_hosts.size(); i < sz; i++) { - err += connect(m_hosts[i], client_options); + ret += clientConnect(m_hosts[i], client_options); } - return err; + return ret; } -int distrib::connect(const string & host, +int distrib::clientConnect(const string & host, const std::vector & client_options) { int id = fork(); @@ -59,6 +61,7 @@ int distrib::connect(const string & host, else if (id > 0) /* in the parent */ { m_children.push_back(id); + m_num_clients++; } else /* in the child */ { @@ -144,8 +147,10 @@ void distrib_server(distrib * the_distrib) int distrib::startServer() { + m_server = true; + pthread_mutex_lock(&m_listen_mutex); - + /* start the listen thread */ int ret = pthread_create(&m_server_thread, NULL, @@ -163,5 +168,45 @@ int distrib::startServer() int distrib::startClient(const char * server, int port) { + m_server = false; + + m_client_socket = socket(PF_INET, SOCK_STREAM, 0); + if (m_client_socket < 0) + { + cerr << "Error creating client socket: " << errno << endl; + return 1; + } + + struct addrinfo hint; + memset(&hint, 0, sizeof(hint)); + hint.ai_family = AF_INET; + hint.ai_socktype = SOCK_STREAM; + + struct addrinfo * res; + char portstr[15]; + sprintf(portstr, "%d", port); + getaddrinfo(server, portstr, &hint, &res); + + if (connect(m_client_socket, res->ai_addr, res->ai_addrlen) == -1) + { + cerr << "Error connecting from client socket: " << errno << endl; + return 2; + } + return 0; } + +int distrib::send_data(int task, unsigned char * data, int num_bytes) +{ +} + +int distrib::getTask() +{ + if (m_server) + { + } + else + { + } + return -1; +} diff --git a/distrib/distrib.h b/distrib/distrib.h index 3027658..0635394 100644 --- a/distrib/distrib.h +++ b/distrib/distrib.h @@ -14,20 +14,29 @@ class distrib int startServer(); int startClient(const char * server, int port); int startClients(const std::vector & client_options); + int getNumClients() { return m_num_clients; } + void set_data(unsigned char * data) { m_data = data; } + int getTask(); + int send_data(int task, unsigned char * data, int num_bytes); + friend void distrib_server(distrib * the_distrib); protected: - int connect(const std::string & host, - const std::vector & client_options); + int clientConnect(const std::string & host, + const std::vector & client_options); std::vector m_hosts; std::vector m_children; std::string m_servername; int m_serverport; int m_listen_socket; + int m_client_socket; pthread_t m_server_thread; pthread_cond_t m_listen_cond; pthread_mutex_t m_listen_mutex; + int m_num_clients; + unsigned char * m_data; + bool m_server; }; #endif diff --git a/main/Scene.cc b/main/Scene.cc index 2c3effd..2b0c83d 100644 --- a/main/Scene.cc +++ b/main/Scene.cc @@ -125,34 +125,77 @@ Scene::~Scene() void Scene::render() { - if (m_verbose && m_server) + if (m_server) { - cout << " *** Beginning scene render ***" << endl; - cout << "Parameters:" << endl; - cout << "----------------------------------------" << endl; - cout << " Width: " << m_width << endl; - cout << " Height: " << m_height << endl; - cout << " Multisample Level: " << m_multisample_level << endl; - cout << " Vertical Field of View: " << m_vfov << endl; - cout << "----------------------------------------" << endl; - } - - m_data = new unsigned char[m_width * m_height * 3]; - - for (int i = 0; i < m_height; i++) - { - for (int j = 0; j < m_width; j++) + /* server version */ + if (m_verbose) { - renderPixel(j, i, &m_data[3 * (m_width * i + j)]); + cout << " *** Beginning scene render ***" << endl; + cout << "Parameters:" << endl; + cout << "----------------------------------------" << endl; + cout << " Width: " << m_width << endl; + cout << " Height: " << m_height << endl; + cout << " Multisample Level: " << m_multisample_level << endl; + cout << " Vertical Field of View: " << m_vfov << endl; + cout << "----------------------------------------" << endl; } - } - if (m_verbose && m_server) - { - cout << " *** Ending scene render ***" << endl; - cout << "Writing output file '" << m_output_file_name << '\'' << endl; + m_data = new unsigned char[m_width * m_height * 3]; /* 24bpp */ + + if (m_distrib.getNumClients() < 1) + { + for (int i = 0; i < m_height; i++) + { + for (int j = 0; j < m_width; j++) + { + renderPixel(j, i, &m_data[3 * (m_width * i + j)]); + } + } + } + else + { + m_distrib.set_data(m_data); + /* work on tasks in this thread until there are no more */ + taskLoop(); + } + + if (m_verbose) + { + cout << " *** Ending scene render ***" << endl; + cout << "Writing output file '" << m_output_file_name + << '\'' << endl; + } + BMP outputImage(m_output_file_name.c_str(), m_width, m_height, m_data); + } + else + { + /* client version */ + taskLoop(); + } +} + +void Scene::taskLoop() +{ + for (;;) + { + int task_id = m_distrib.getTask(); + if (task_id < 0) + break; + unsigned char data[3 * UNIT_TASK_SIZE]; + int i = task_id / m_width; + int j = task_id % m_width; + for (int t = 0; t < UNIT_TASK_SIZE; t++) + { + renderPixel(j, i, &data[3 * t]); + j++; + if (j == m_width) + { + j = 0; + i++; + } + } + m_distrib.send_data(task_id, data, 3 * UNIT_TASK_SIZE); } - BMP outputImage(m_output_file_name.c_str(), m_width, m_height, m_data); } void Scene::renderPixel(int x, int y, unsigned char * pixel) diff --git a/main/Scene.h b/main/Scene.h index a7697f7..2f2daf0 100644 --- a/main/Scene.h +++ b/main/Scene.h @@ -23,6 +23,7 @@ #include "Light.h" #define SCENE_FACTOR_THRESHOLD 0.02 +#define UNIT_TASK_SIZE 50 class Scene { @@ -49,6 +50,7 @@ class Scene const Vector & surfaceNormal); Color calculateLightContribution(const Ray & toLight, refptr light); + void taskLoop(); /* In Scene-load.cc */ void load(const char * filename); diff --git a/main/fart.cc b/main/fart.cc index 3966cf2..6f2c288 100644 --- a/main/fart.cc +++ b/main/fart.cc @@ -124,11 +124,11 @@ int main(int argc, char * argv[]) { cout << " ("; if (days) - cout << days << " days, "; + cout << days << (days == 1 ? " day, " : " days, "); if (days || hours) - cout << hours << " hours, "; - cout << minutes << " minutes, "; - cout << seconds << " seconds)"; + cout << hours << (hours == 1 ? " hour, " : " hours, "); + cout << minutes << (minutes == 1 ? " minute, " : " minutes, "); + cout << seconds << (seconds == 1 ? " second)" : " seconds)"); } cout << endl; }