Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace pthread with boost::thread #1000

Merged
merged 3 commits into from
Aug 28, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ endif
LIBRARIES += \
glog gflags pthread protobuf leveldb snappy \
lmdb \
boost_system \
boost_system boost_thread \
hdf5_hl hdf5 \
opencv_core opencv_highgui opencv_imgproc
PYTHON_LIBRARIES := boost_python python2.7
Expand Down
32 changes: 13 additions & 19 deletions include/caffe/internal_thread.hpp
Original file line number Diff line number Diff line change
@@ -1,42 +1,36 @@
#ifndef CAFFE_INTERNAL_THREAD_HPP_
#define CAFFE_INTERNAL_THREAD_HPP_

#include <pthread.h>
#include <boost/thread.hpp>

#include "caffe/common.hpp"

namespace caffe {

/**
* Virutal class encapsulate pthread for use in base class
* The child class will acquire the ability to run a single pthread,
* Virutal class encapsulate boost::thread for use in base class
* The child class will acquire the ability to run a single thread,
* by reimplementing the virutal function InternalThreadEntry.
*/
class InternalThread {
public:
InternalThread() {}
virtual ~InternalThread() {}
InternalThread() : thread_(NULL) {}
virtual ~InternalThread();

/** Returns true if the thread was successfully started. **/
bool StartInternalThread() {
return (pthread_create(&_thread, NULL, InternalThreadEntryFunc, this) == 0);
}
bool StartInternalThread();

/** Will not return until the internal thread has exited. */
bool WaitForInternalThreadToExit() {
return pthread_join(_thread, NULL);
}
bool WaitForInternalThreadToExit();

bool is_started() const { return thread_ != NULL && thread_->joinable(); }

protected:
/* Implement this method in your subclass
with the code you want your thread to run. */
virtual void InternalThreadEntry() = 0;

private:
static void * InternalThreadEntryFunc(void * This) {
reinterpret_cast<InternalThread *>(This)->InternalThreadEntry();
return NULL;
}
virtual void InternalThreadEntry() {}

pthread_t _thread;
boost::thread* thread_;
};

} // namespace caffe
Expand Down
2 changes: 1 addition & 1 deletion scripts/travis/travis_install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ sudo apt-get install \
wget git curl \
python-dev python-numpy \
libleveldb-dev libsnappy-dev libopencv-dev \
libboost-dev libboost-system-dev libboost-python-dev \
libboost-dev libboost-system-dev libboost-python-dev libboost-thread-dev \
libprotobuf-dev protobuf-compiler \
libatlas-dev libatlas-base-dev \
libhdf5-serial-dev \
Expand Down
11 changes: 6 additions & 5 deletions src/caffe/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ find_package(LMDB REQUIRED)
include_directories(${LMDB_INCLUDE_DIR})

# Boost
find_package(Boost 1.46 COMPONENTS system REQUIRED)
find_package(Boost 1.46 COMPONENTS system thread REQUIRED)
include_directories( ${Boost_INCLUDE_DIR} )
link_directories( ${Boost_LIBRARY_DIRS} )

Expand Down Expand Up @@ -99,14 +99,15 @@ if(NOT CPU_ONLY)
endif()

target_link_libraries(caffe proto
${GLOG_LIBRARIES}
${BLAS_LIBRARIES}
${Boost_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
${GFLAGS_LIBRARIES}
${GLOG_LIBRARIES}
${HDF5_LIBRARIES}
${OpenCV_LIBS}
${LEVELDB_LIBS}
${LMDB_LIBRARIES}
${BLAS_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
${OpenCV_LIBS}
)

#set output directory
Expand Down
33 changes: 33 additions & 0 deletions src/caffe/internal_thread.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "caffe/internal_thread.hpp"

namespace caffe {

InternalThread::~InternalThread() {
WaitForInternalThreadToExit();
if (thread_ != NULL) {
delete thread_;
}
}

bool InternalThread::StartInternalThread() {
try {
thread_ = new boost::thread(&InternalThread::InternalThreadEntry, this);
} catch (...) {
return false;
}
return true;
}

/** Will not return until the internal thread has exited. */
bool InternalThread::WaitForInternalThreadToExit() {
if (is_started()) {
try {
thread_->join();
} catch (...) {
return false;
}
}
return true;
}

} // namespace caffe
4 changes: 2 additions & 2 deletions src/caffe/layers/data_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,12 +244,12 @@ void DataLayer<Dtype>::CreatePrefetchThread() {

data_transformer_.InitRand();

CHECK(StartInternalThread()) << "Pthread execution failed";
CHECK(StartInternalThread()) << "Thread execution failed";
}

template <typename Dtype>
void DataLayer<Dtype>::JoinPrefetchThread() {
CHECK(!WaitForInternalThreadToExit()) << "Pthread joining failed";
CHECK(WaitForInternalThreadToExit()) << "Thread joining failed";
}

template <typename Dtype>
Expand Down
4 changes: 2 additions & 2 deletions src/caffe/layers/image_data_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ void ImageDataLayer<Dtype>::CreatePrefetchThread() {
data_transformer_.InitRand();

// Create the thread.
CHECK(StartInternalThread()) << "Pthread execution failed";
CHECK(StartInternalThread()) << "Thread execution failed";
}

template <typename Dtype>
Expand All @@ -172,7 +172,7 @@ void ImageDataLayer<Dtype>::ShuffleImages() {

template <typename Dtype>
void ImageDataLayer<Dtype>::JoinPrefetchThread() {
CHECK(!WaitForInternalThreadToExit()) << "Pthread joining failed";
CHECK(WaitForInternalThreadToExit()) << "Thread joining failed";
}

template <typename Dtype>
Expand Down
4 changes: 2 additions & 2 deletions src/caffe/layers/window_data_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,12 +408,12 @@ void WindowDataLayer<Dtype>::CreatePrefetchThread() {
prefetch_rng_.reset();
}
// Create the thread.
CHECK(StartInternalThread()) << "Pthread execution failed.";
CHECK(StartInternalThread()) << "Thread execution failed.";
}

template <typename Dtype>
void WindowDataLayer<Dtype>::JoinPrefetchThread() {
CHECK(!WaitForInternalThreadToExit()) << "Pthread joining failed.";
CHECK(WaitForInternalThreadToExit()) << "Thread joining failed.";
}

template <typename Dtype>
Expand Down
23 changes: 23 additions & 0 deletions src/caffe/test/test_internal_thread.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "glog/logging.h"
#include "gtest/gtest.h"

#include "caffe/internal_thread.hpp"

#include "caffe/test/test_caffe_main.hpp"

namespace caffe {


class InternalThreadTest : public ::testing::Test {};

TEST_F(InternalThreadTest, TestStartAndExit) {
InternalThread thread;
EXPECT_FALSE(thread.is_started());
EXPECT_TRUE(thread.StartInternalThread());
EXPECT_TRUE(thread.is_started());
EXPECT_TRUE(thread.WaitForInternalThreadToExit());
EXPECT_FALSE(thread.is_started());
}

} // namespace caffe