Browse Source

Merge pull request #1928 from matt-42/master

[C++/silicon] Add the silicon lwan backend
Mike Smith 9 years ago
parent
commit
d78ff9f791

+ 6 - 3
frameworks/C++/silicon/CMakeLists.txt

@@ -6,11 +6,14 @@ include_directories($ENV{IROOT}/include $ENV{MICROHTTPD_HOME}/include)
 
 link_directories($ENV{IROOT}/lib $ENV{MICROHTTPD_HOME}/lib)
 
-add_definitions(-std=c++14  -ftemplate-depth=512 -DNDEBUG -O3)
+add_definitions(-std=c++14 -ftemplate-depth=1024 -DNDEBUG -O3)
 
-add_executable(silicon_tpc_mysql main.cc)
+add_executable(silicon_tpc_mysql techempower_microhttpd.cc)
 target_link_libraries(silicon_tpc_mysql microhttpd mysqlclient)
 
-add_executable(silicon_epoll_mysql main.cc)
+add_executable(silicon_epoll_mysql techempower_microhttpd.cc)
 set_target_properties(silicon_epoll_mysql PROPERTIES COMPILE_FLAGS "-DTFB_USE_EPOLL")
 target_link_libraries(silicon_epoll_mysql microhttpd mysqlclient)
+
+add_executable(silicon_lwan_mysql techempower_lwan.cc)
+target_link_libraries(silicon_lwan_mysql mysqlclient lwan-common curl z pthread dl)

+ 28 - 4
frameworks/C++/silicon/benchmark_config.json

@@ -2,7 +2,7 @@
   "framework": "silicon",
   "tests": [{
     "default": {
-      "setup_file": "setup_tpc_mysql",
+      "setup_file": "setup_mhd_tpc_mysql",
       "json_url"       : "/json",
       "db_url"         : "/db",
       "query_url"      : "/queries?queries=",
@@ -17,7 +17,7 @@
       "language": "C++",
       "orm": "Full",
       "platform": "Silicon",
-      "webserver": "None",
+      "webserver": "microhttpd",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "silicon-tpc-mysql",
@@ -25,7 +25,7 @@
       "versus": ""
     },
     "epoll-mysql": {
-      "setup_file": "setup_epoll_mysql",
+      "setup_file": "setup_mhd_epoll_mysql",
       "json_url"       : "/json",
       "db_url"         : "/db",
       "query_url"      : "/queries?queries=",
@@ -40,12 +40,36 @@
       "language": "C++",
       "orm": "Full",
       "platform": "Silicon",
-      "webserver": "None",
+      "webserver": "microhttpd",
       "os": "Linux",
       "database_os": "Linux",
       "display_name": "silicon-epoll-mysql",
       "notes": "",
       "versus": ""
+    },
+    "lwan-mysql": {
+      "setup_file": "setup_lwan_mysql",
+      "json_url"       : "/json",
+      "db_url"         : "/db",
+      "query_url"      : "/queries?queries=",
+      "fortune_url"    : "/fortunes",
+      "update_url"     : "/updates?queries=",
+      "plaintext_url"  : "/plaintext",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Micro",
+      "database": "MySQL",
+      "framework": "silicon",
+      "language": "C++",
+      "orm": "Full",
+      "platform": "Silicon",
+      "webserver": "Lwan",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "silicon-lwan-mysql",
+      "notes": "",
+      "versus": ""
     }
+    
   }]
 }

+ 0 - 137
frameworks/C++/silicon/main.cc

@@ -1,137 +0,0 @@
-#include <algorithm>
-#include <unistd.h>
-#include <iostream>
-#include <silicon/backends/mhd.hh>
-#include <silicon/api.hh>
-#include <silicon/middlewares/mysql_connection.hh>
-#include <silicon/middlewares/mysql_orm.hh>
-#include "symbols.hh"
-
-using namespace s;
-using namespace sl;
-
-typedef decltype(D(_id(_auto_increment, _primary_key) = int(),
-                   _randomNumber = int())) random_number;
-
-typedef decltype(D(_id(_auto_increment, _primary_key) = int(),
-                   _message = std::string())) fortune;
-
-typedef mysql_orm_factory<random_number> rn_orm_factory;
-typedef mysql_orm<random_number> rn_orm;
-
-typedef mysql_orm_factory<fortune> fortune_orm_factory;
-typedef mysql_orm<fortune> fortune_orm;
-
-std::string escape_html_entities(const std::string& data)
-{
-    std::string buffer;
-    buffer.reserve(data.size());
-    for(size_t pos = 0; pos != data.size(); ++pos) {
-        switch(data[pos]) {
-            case '&':  buffer.append("&amp;");       break;
-            case '\"': buffer.append("&quot;");      break;
-            case '\'': buffer.append("&apos;");      break;
-            case '<':  buffer.append("&lt;");        break;
-            case '>':  buffer.append("&gt;");        break;
-            default:   buffer.append(&data[pos], 1); break;
-        }
-    }
-    return std::move(buffer);
-}
-
-int main(int argc, char* argv[])
-{
-
-  if (argc != 4)
-  {
-    std::cerr << "Usage: " << argv[0] << " mysql_host port nthreads" << std::endl;
-    return 1;
-  }
-  
-  auto hello_api = make_api(
-
-    _plaintext = [] () { return response(_content_type = "text/plain",
-                                         _body = "Hello, World!"); },
-
-    _json = [] () { return response(_content_type = "application/json",
-                                    _body = D(_message = "Hello, World!")); },
-                        
-    _db = [] (rn_orm& orm) {
-      random_number r;
-      orm.find_by_id(1245, r);
-      return response(_content_type = "application/json",
-                      _body = r);
-    },
-
-    _queries = [] (rn_orm& orm, get_parameters& get_params) {
-      int N = atoi(get_params["queries"].c_str());
-      N = std::max(1, std::min(N, 500));
-
-      std::vector<random_number> qs(N);
-      for (int i = 0; i < N; i++)
-        orm.find_by_id(1 + rand() % 9999, qs[i]);
-      return response(_content_type = "application/json",
-                      _body = std::move(qs));
-    },
-
-    _updates = [] (rn_orm& orm, get_parameters& get_params) {
-      int N = atoi(get_params["queries"].c_str());
-      N = std::max(1, std::min(N, 500));
-
-      std::vector<random_number> qs(N);
-      for (int i = 0; i < N; i++)
-      {
-        orm.find_by_id(1 + rand() % 9999, qs[i]);
-        qs[i].randomNumber = 1 + rand() % 9999;
-        orm.update(qs[i]);
-      }
-      return response(_content_type = "application/json",
-                      _body = std::move(qs));
-    },
-  
-    _fortunes = [] (fortune_orm& orm) {
-      std::vector<fortune> table;
-      orm.forall([&] (fortune& f) { table.push_back(f); });
-      table.push_back(fortune(0, "Additional fortune added at request time."));
-
-      std::sort(table.begin(), table.end(),
-                [] (const fortune& a, const fortune& b) { return a.message < b.message; });
-
-      std::stringstream ss;
-
-      ss << "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>";
-      for(auto& f : table)
-        ss << "<tr><td>" << f.id << "</td><td>" << escape_html_entities(f.message) << "</td></tr>";
-      ss << "</table></body></html>";
-
-      return response(_content_type = "text/html",
-                      _body = ss.str());
-    }
-  
-    ).bind_factories(
-      mysql_connection_factory(argv[1], "benchmarkdbuser", "benchmarkdbpass", "hello_world"),
-      fortune_orm_factory("Fortune"),
-      rn_orm_factory("World")
-      );
-  
-  try
-  {
-
-    // Start the server.
-    sl::mhd_json_serve(hello_api, atoi(argv[2])
-#ifdef TFB_USE_EPOLL
-                       , _linux_epoll, _nthreads = atoi(argv[3])
-#else
-                       , _one_thread_per_connection
-#endif
-      );
-  }
-  catch (std::exception& e)
-  {
-    std::cerr << e.what() << std::endl;
-  }
-  catch (sl::error::error& e)
-  {
-    std::cerr << e.what() << std::endl;
-  }
-}

+ 11 - 0
frameworks/C++/silicon/setup_lwan_mysql.sh

@@ -0,0 +1,11 @@
+#! /bin/bash
+
+fw_depends silicon lwan
+
+rm -rf build
+mkdir build
+cd build
+cmake .. -DCMAKE_CXX_COMPILER=clang++-3.5
+make silicon_lwan_mysql
+
+$TROOT/build/silicon_lwan_mysql ${DBHOST} 8080 &

+ 1 - 1
frameworks/C++/silicon/setup_epoll_mysql.sh → frameworks/C++/silicon/setup_mhd_epoll_mysql.sh

@@ -5,7 +5,7 @@ fw_depends silicon microhttpd
 rm -rf build
 mkdir build
 cd build
-cmake .. -DCMAKE_CXX_COMPILER=g++-4.9
+cmake .. -DCMAKE_CXX_COMPILER=clang++-3.5
 make silicon_epoll_mysql
 
 $TROOT/build/silicon_epoll_mysql ${DBHOST} 8080 ${MAX_THREADS} &

+ 1 - 1
frameworks/C++/silicon/setup_tpc_mysql.sh → frameworks/C++/silicon/setup_mhd_tpc_mysql.sh

@@ -5,7 +5,7 @@ fw_depends silicon microhttpd
 rm -rf build
 mkdir build
 cd build
-cmake .. -DCMAKE_CXX_COMPILER=g++-4.9
+cmake .. -DCMAKE_CXX_COMPILER=clang++-3.5
 make silicon_tpc_mysql
 
 $TROOT/build/silicon_tpc_mysql ${DBHOST} 8080 ${MAX_THREADS} &

+ 103 - 0
frameworks/C++/silicon/techempower.hh

@@ -0,0 +1,103 @@
+#include <unistd.h>
+#include <iostream>
+#include <silicon/api.hh>
+#include <silicon/middleware_factories.hh>
+#include <silicon/middlewares/mysql_connection.hh>
+#include <silicon/middlewares/mysql_orm.hh>
+#include "symbols.hh"
+
+using namespace s;
+using namespace sl;
+
+typedef decltype(D(_id(_auto_increment, _primary_key) = int(),
+                   _randomNumber = int())) random_number;
+
+typedef decltype(D(_id(_auto_increment, _primary_key) = int(),
+                   _message = std::string())) fortune;
+
+typedef mysql_orm_factory<random_number> rn_orm_factory;
+typedef mysql_orm<random_number> rn_orm;
+
+typedef mysql_orm_factory<fortune> fortune_orm_factory;
+typedef mysql_orm<fortune> fortune_orm;
+
+
+std::string escape_html_entities(std::string& data)
+{
+    std::string buffer;
+    buffer.reserve(data.size());
+    for(size_t pos = 0; pos != data.size(); ++pos) {
+        switch(data[pos]) {
+            case '&':  buffer.append("&amp;");       break;
+            case '\"': buffer.append("&quot;");      break;
+            case '\'': buffer.append("&apos;");      break;
+            case '<':  buffer.append("&lt;");        break;
+            case '>':  buffer.append("&gt;");        break;
+            default:   buffer.append(&data[pos], 1); break;
+        }
+    }
+    return std::move(buffer);
+}
+
+auto techempower_api = http_api(
+
+
+  GET / _plaintext = [] () { return response(_content_type = string_ref("text/plain"),
+                                       _body = string_ref("Hello, World!")); },
+
+  GET / _json = [] () { return response(_content_type = string_ref("application/json"),
+                                  _body = D(_message = string_ref("Hello, World!"))); },
+                        
+  GET / _db = [] (rn_orm& orm) {
+    random_number r;
+    orm.find_by_id(1245, r);
+    return response(_content_type = "application/json",
+                    _body = r);
+  },
+
+  GET / _queries * get_parameters(_queries = optional(std::string("1"))) = [] (auto param, rn_orm& orm) {
+    int N = atoi(param.queries.c_str());
+    N = std::max(1, std::min(N, 500));
+
+    std::vector<random_number> qs(N);
+    for (int i = 0; i < N; i++)
+      orm.find_by_id(1 + rand() % 9999, qs[i]);
+    return response(_content_type = "application/json",
+                    _body = std::move(qs));
+  },
+
+  GET / _updates * get_parameters(_queries = optional(std::string("1"))) = [] (auto param, rn_orm& orm) {
+    int N = atoi(param.queries.c_str());
+    N = std::max(1, std::min(N, 500));
+
+    std::vector<random_number> qs(N);
+    for (int i = 0; i < N; i++)
+    {
+      orm.find_by_id(1 + rand() % 9999, qs[i]);
+      qs[i].randomNumber = 1 + rand() % 9999;
+      orm.update(qs[i]);
+    }
+    return response(_content_type = "application/json",
+                    _body = std::move(qs));
+  },
+  
+  GET / _fortunes = [] (fortune_orm& orm) {
+    std::vector<fortune> table;
+    orm.forall([&] (fortune& f) { table.push_back(f); });
+    table.push_back(fortune(0, "Additional fortune added at request time."));
+
+    std::sort(table.begin(), table.end(),
+              [] (const fortune& a, const fortune& b) { return a.message < b.message; });
+
+    std::stringstream ss;
+
+    ss << "<!DOCTYPE html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>";
+    for(auto& f : table)
+      ss << "<tr><td>" << f.id << "</td><td>" << escape_html_entities(f.message) << "</td></tr>";
+    ss << "</table></body></html>";
+
+    return response(_content_type = "text/html; charset=utf-8",
+                    _body = ss.str());
+  }
+  
+  );

+ 41 - 0
frameworks/C++/silicon/techempower_lwan.cc

@@ -0,0 +1,41 @@
+#include <silicon/backends/lwan.hh>
+
+#include "techempower.hh"
+
+using namespace s;
+using namespace sl;
+
+int main(int argc, char* argv[])
+{
+  if (argc != 3)
+  {
+    std::cerr << "Usage: " << argv[0] << " mysql_host port" << std::endl;
+    return 1;
+  }
+
+  auto techempower_middlewares = middleware_factories(
+    mysql_connection_factory(argv[1], "benchmarkdbuser", "benchmarkdbpass", "hello_world"),
+    fortune_orm_factory("Fortune"),
+    rn_orm_factory("World")
+    );
+  
+  try
+  {
+
+    // Write the pid.
+    std::ofstream pidfile(argv[3]);
+    pidfile << getpid() << std::endl;
+    pidfile.close();
+
+    // Start the server.
+    sl::lwan_json_serve(techempower_api, techempower_middlewares, atoi(argv[2]));
+  }
+  catch (std::exception& e)
+  {
+    std::cerr << e.what() << std::endl;
+  }
+  catch (sl::error::error& e)
+  {
+    std::cerr << e.what() << std::endl;
+  }
+}

+ 48 - 0
frameworks/C++/silicon/techempower_microhttpd.cc

@@ -0,0 +1,48 @@
+#include <silicon/backends/mhd.hh>
+
+#include "techempower.hh"
+
+using namespace s;
+using namespace sl;
+
+int main(int argc, char* argv[])
+{
+
+  if (argc != 4)
+  {
+    std::cerr << "Usage: " << argv[0] << " mysql_host port nthreads" << std::endl;
+    return 1;
+  }
+
+  auto techempower_middlewares = middleware_factories(
+    mysql_connection_factory(argv[1], "benchmarkdbuser", "benchmarkdbpass", "hello_world"),
+    fortune_orm_factory("Fortune"),
+    rn_orm_factory("World")
+    );
+  
+  try
+  {
+    // Write the pid.
+    std::ofstream pidfile(argv[3]);
+    pidfile << getpid() << std::endl;
+    pidfile.close();
+
+    // Start the server.
+    sl::mhd_json_serve(techempower_api, techempower_middlewares, atoi(argv[2]), _blocking
+#ifdef TFB_USE_EPOLL
+                       , _linux_epoll, _nthreads = atoi(argv[3])
+#else
+                       , _one_thread_per_connection
+#endif
+      );
+    
+  }
+  catch (std::exception& e)
+  {
+    std::cerr << e.what() << std::endl;
+  }
+  catch (sl::error::error& e)
+  {
+    std::cerr << e.what() << std::endl;
+  }
+}

+ 4 - 2
toolset/setup/linux/frameworks/lwan.sh

@@ -5,7 +5,8 @@ RETCODE=$(fw_exists ${IROOT}/lwan.installed)
   source $IROOT/lwan.installed
   return 0; }
 
-REV='49607addb31879e2aa2b701317773674662315aa'
+#REV='49607addb31879e2aa2b701317773674662315aa'
+REV='0a4af6feb3ba1a7a7d6aa122456dd78c4a29853b'
 LWAN_HOME=$IROOT/lwan
 
 [ ! -e $IROOT/lwan.installed -a -d $LWAN_HOME ] && rm -rf $LWAN_HOME
@@ -16,8 +17,9 @@ cd $LWAN_HOME
 git checkout ${REV}
 mkdir build
 cd build
-cmake .. -DCMAKE_BUILD_TYPE=Release
+cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$IROOT
 make techempower
+make install
 
 echo "export LWAN_ROOT=${LWAN_HOME}" > $IROOT/lwan.installed
 echo -e "export LWAN_BUILD=\$LWAN_ROOT/build" >> $IROOT/lwan.installed

+ 2 - 2
toolset/setup/linux/frameworks/silicon.sh

@@ -10,8 +10,8 @@ SILICON=$IROOT/silicon
 
 git clone https://github.com/matt-42/silicon.git
 cd silicon;
-git checkout 17167fd6065b1fd4e628a81f2327121d9f733298
-CXX=/usr/bin/g++-4.9 ./install.sh $IROOT
+git checkout a2b930696a72aa963056f21b1605adfe8ec1a8a7
+CXX=clang++-3.5 ./install.sh $IROOT
 
 echo "" > $IROOT/silicon.installed
 

+ 2 - 2
toolset/setup/linux/prerequisites.sh

@@ -62,10 +62,10 @@ sudo pip install colorama==0.3.1
 sudo pip install progressbar==2.2
 sudo pip install requests
 
-# Install gcc-4.8 and gcc-4.9
+# Install gcc-4.8, gcc-4.9 and clang
 sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
 sudo apt-get -yq update
-sudo apt-get install -qqy gcc-4.8 g++-4.8 gcc-4.9 g++-4.9
+sudo apt-get install -qqy gcc-4.8 g++-4.8 gcc-4.9 g++-4.9 clang-3.5
 
 # Stop permanently overwriting people's files just for 
 # trying out our software!