提交 db13fddc 编写于 作者: Y Yu Yang

Clean locks.h, Add arch Locks.cpp

上级 738b6894
*.DS_Store
build/
*.user
......@@ -2,11 +2,17 @@
file(GLOB UTIL_HEADERS . *.h)
file(GLOB UTIL_SOURCES . *.cpp)
if(APPLE)
file(GLOB UTIL_ARCH_SOURCES . arch/osx/*.cpp)
else()
file(GLOB UTIL_ARCH_SOURCES . arch/linux/*.cpp)
endif()
add_library(paddle_utils STATIC
${UTIL_SOURCES})
${UTIL_SOURCES}
${UTIL_ARCH_SOURCES})
add_style_check_target(paddle_utils ${UTIL_HEADERS})
add_style_check_target(paddle_utils ${UTIL_SOURCES})
add_style_check_target(paddle_utils ${UTIL_SOURCES}
${UTIL_ARCH_SOURCES})
add_dependencies(paddle_utils gen_proto_cpp)
if(WITH_TESTING)
add_subdirectory(tests)
......
/* Copyright (c) 2016 Baidu, Inc. All Rights Reserve.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#ifdef __APPLE__
#include <dispatch/dispatch.h>
#endif
#ifdef __APPLE__
#ifndef PTHREAD_BARRIER_H_
#define PTHREAD_BARRIER_H_
#include <pthread.h>
#include <errno.h>
typedef int pthread_barrierattr_t;
typedef struct {
pthread_mutex_t mutex;
pthread_cond_t cond;
int count;
int tripCount;
} pthread_barrier_t;
int pthread_barrier_init(pthread_barrier_t *barrier,
const pthread_barrierattr_t *attr, unsigned int count) {
if (count == 0) {
errno = EINVAL;
return -1;
}
if (pthread_mutex_init(&barrier->mutex, 0) < 0) {
return -1;
}
if (pthread_cond_init(&barrier->cond, 0) < 0) {
pthread_mutex_destroy(&barrier->mutex);
return -1;
}
barrier->tripCount = count;
barrier->count = 0;
return 0;
}
int pthread_barrier_destroy(pthread_barrier_t *barrier) {
pthread_cond_destroy(&barrier->cond);
pthread_mutex_destroy(&barrier->mutex);
return 0;
}
int pthread_barrier_wait(pthread_barrier_t *barrier) {
pthread_mutex_lock(&barrier->mutex);
++(barrier->count);
if (barrier->count >= barrier->tripCount) {
barrier->count = 0;
pthread_cond_broadcast(&barrier->cond);
pthread_mutex_unlock(&barrier->mutex);
return 1;
} else {
pthread_cond_wait(&barrier->cond, &(barrier->mutex));
pthread_mutex_unlock(&barrier->mutex);
return 0;
}
}
#endif // PTHREAD_BARRIER_H_
typedef int pthread_spinlock_t;
int pthread_spin_init(pthread_spinlock_t *lock, int pshared) {
__asm__ __volatile__("" ::: "memory");
*lock = 0;
return 0;
}
int pthread_spin_destroy(pthread_spinlock_t *lock) {
return 0;
}
int pthread_spin_lock(pthread_spinlock_t *lock) {
while (1) {
int i;
for (i=0; i < 10000; i++) {
if (__sync_bool_compare_and_swap(lock, 0, 1)) {
return 0;
}
}
sched_yield();
}
}
int pthread_spin_unlock(pthread_spinlock_t *lock) {
__asm__ __volatile__("" ::: "memory");
*lock = 0;
return 0;
}
#endif // __APPLE__
......@@ -16,56 +16,11 @@ limitations under the License. */
#pragma once
#include <pthread.h>
#include <semaphore.h>
#include <sys/time.h>
#include <unistd.h>
#include <condition_variable>
#include <mutex>
#ifdef __APPLE__
#include <dispatch/dispatch.h>
#endif
#ifdef __APPLE__
#ifndef PTHREAD_BARRIER_H_
#define PTHREAD_BARRIER_H_
#include <pthread.h>
#include <errno.h>
typedef int pthread_barrierattr_t;
typedef struct {
pthread_mutex_t mutex;
pthread_cond_t cond;
int count;
int tripCount;
} pthread_barrier_t;
extern int pthread_barrier_init(pthread_barrier_t *barrier,
const pthread_barrierattr_t *attr,
unsigned int count);
extern int pthread_barrier_destroy(pthread_barrier_t *barrier);
extern int pthread_barrier_wait(pthread_barrier_t *barrier);
#endif // PTHREAD_BARRIER_H_
typedef int pthread_spinlock_t;
extern int pthread_spin_init(pthread_spinlock_t *lock, int pshared);
extern int pthread_spin_destroy(pthread_spinlock_t *lock);
extern int pthread_spin_lock(pthread_spinlock_t *lock);
extern int pthread_spin_unlock(pthread_spinlock_t *lock);
#endif
#include "DisableCopy.h"
namespace paddle {
......@@ -142,58 +97,44 @@ protected:
* which means it will keep trying to lock until lock on successfully.
* The SpinLock disable copy.
*/
class SpinLockPrivate;
class SpinLock {
public:
SpinLock() { pthread_spin_init(&lock_, 0); }
~SpinLock() { pthread_spin_destroy(&lock_); }
SpinLock(const SpinLock&) = delete;
SpinLock& operator=(const SpinLock&) = delete;
DISABLE_COPY(SpinLock);
SpinLock();
~SpinLock();
// std::mutext interface
void lock() { pthread_spin_lock(&lock_); }
void unlock() { pthread_spin_unlock(&lock_); }
void lock();
void unlock();
protected:
pthread_spinlock_t lock_;
char padding_[64 - sizeof(pthread_spinlock_t)];
private:
SpinLockPrivate* m;
};
/**
* A simple wapper of semaphore which can only be shared in the same process.
*/
#ifdef __APPLE__
class SemaphorePrivate;
class Semaphore {
public:
explicit Semaphore(int initValue = 0) {
sem_ = dispatch_semaphore_create(initValue);
}
//! Disable copy & assign
Semaphore(const Semaphore& other) = delete;
Semaphore& operator= (const Semaphore&& other) = delete;
~Semaphore() { dispatch_release(sem_); }
bool timeWait(struct timespec* ts) {
dispatch_time_t m = dispatch_walltime(ts, 0);
return (0 == dispatch_semaphore_wait(sem_, m));
//! Enable move.
Semaphore(Semaphore&& other): m(std::move(other.m)) {
}
void wait() { dispatch_semaphore_wait(sem_, DISPATCH_TIME_FOREVER); }
void post() { dispatch_semaphore_signal(sem_);}
protected:
dispatch_semaphore_t sem_;
};
#else
class Semaphore {
public:
/**
* @brief Construct Function.
* @param[in] initValue the initial value of the
* semaphore, default 0.
*/
explicit Semaphore(int initValue = 0) { sem_init(&sem_, 0, initValue); }
explicit Semaphore(int initValue = 0);
~Semaphore() { sem_destroy(&sem_); }
~Semaphore();
/**
* @brief The same as wait(), except if the decrement can not
......@@ -203,43 +144,38 @@ public:
* @return ture if the decrement proceeds before ts,
* else return false.
*/
bool timeWait(struct timespec* ts) { return (0 == sem_timedwait(&sem_, ts)); }
bool timeWait(struct timespec* ts);
/**
* @brief decrement the semaphore. If the semaphore's value is 0, then call blocks.
*/
void wait() { sem_wait(&sem_); }
void wait();
/**
* @brief increment the semaphore. If the semaphore's value
* greater than 0, wake up a thread blocked in wait().
*/
void post() { sem_post(&sem_); }
void post();
protected:
sem_t sem_;
private:
SemaphorePrivate* m;
};
#endif
static_assert(sizeof(SpinLock) == 64, "Wrong padding");
/**
* A simple wrapper of thread barrier.
* The ThreadBarrier disable copy.
*/
class ThreadBarrierPrivate;
class ThreadBarrier {
public:
DISABLE_COPY(ThreadBarrier);
/**
* @brief Construct Function. Initialize the barrier should
* wait for count threads in wait().
*/
explicit ThreadBarrier(int count) {
pthread_barrier_init(&barrier_, NULL, count);
}
~ThreadBarrier() { pthread_barrier_destroy(&barrier_); }
ThreadBarrier(const ThreadBarrier&) = delete;
ThreadBarrier& operator=(const ThreadBarrier&) = delete;
explicit ThreadBarrier(int count);
~ThreadBarrier();
/**
* @brief .
......@@ -247,10 +183,10 @@ public:
* then wake up all the count - 1 threads and continue run together.
* Else block the thread until waked by other thread .
*/
void wait() { pthread_barrier_wait(&barrier_); }
void wait();
protected:
pthread_barrier_t barrier_;
private:
ThreadBarrierPrivate* m;
};
/**
......
/* Copyright (c) 2016 Baidu, Inc. All Rights Reserve.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#include "paddle/util/Locks.h"
#include <semaphore.h>
#include <unistd.h>
namespace paddle {
class SemaphorePrivate {
public:
sem_t sem;
};
Semaphore::Semaphore(int initValue): m(new SemaphorePrivate()) {
sem_init(&m->sem, 0, initValue);
}
Semaphore::~Semaphore() {
sem_destroy(&m->sem);
}
bool Semaphore::timeWait(struct timespec* ts) {
return (0 == sem_timedwait(&m->sem, ts));
}
void Semaphore::wait() {
sem_wait(&m->sem);
}
void Semaphore::post() {
sem_post(&m->sem);
}
class SpinLockPrivate {
public:
inline SpinLockPrivate() { pthread_spin_init(&lock_, 0); }
inline ~SpinLockPrivate() { pthread_spin_destroy(&lock_); }
pthread_spinlock_t lock_;
char padding_[64 - sizeof(pthread_spinlock_t)];
};
SpinLock::SpinLock():m(new SpinLockPrivate()) {}
SpinLock::~SpinLock() { delete m; }
void SpinLock::lock() {
pthread_spin_lock(&m->lock_);
}
void SpinLock::unlock() {
pthread_spin_unlock(&m->lock_);
}
class ThreadBarrierPrivate {
public:
pthread_barrier_t barrier_;
};
ThreadBarrier::ThreadBarrier(int count): m(new ThreadBarrierPrivate()) {
pthread_barrier_init(&m->barrier_, nullptr, count);
}
ThreadBarrier::~ThreadBarrier() {
pthread_barrier_destroy(&m->barrier_);
delete m;
}
void ThreadBarrier::wait() {
pthread_barrier_wait(&m->barrier_);
}
} // namespace paddle
\ No newline at end of file
/* Copyright (c) 2016 Baidu, Inc. All Rights Reserve.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
#include "paddle/utils/Locks.h"
#include "paddle/utils/Logging.h"
#include <dispatch/dispatch.h>
#include <libkern/OSAtomic.h>
namespace paddle {
class SemaphorePrivate {
public:
~SemaphorePrivate() {
dispatch_release(sem);
}
dispatch_semaphore_t sem;
};
Semaphore::Semaphore(int initValue): m(new SemaphorePrivate()) {
m->sem = dispatch_semaphore_create(initValue);
}
Semaphore::~Semaphore() {
delete m;
}
bool Semaphore::timeWait(timespec *ts) {
dispatch_time_t tm = dispatch_walltime(ts, 0);
return (0 == dispatch_semaphore_wait(m->sem, tm));
}
void Semaphore::wait() {
dispatch_semaphore_wait(m->sem, DISPATCH_TIME_FOREVER);
}
void Semaphore::post() {
dispatch_semaphore_signal(m->sem);
}
class SpinLockPrivate {
public:
SpinLockPrivate(): lock_(0) {}
OSSpinLock lock_;
char padding_[64 - sizeof(OSSpinLock)]; // Padding to cache line size
};
SpinLock::SpinLock(): m(new SpinLockPrivate()) {}
SpinLock::~SpinLock() { delete m; }
void SpinLock::lock() {
OSSpinLockLock(&m->lock_);
}
void SpinLock::unlock() {
OSSpinLockUnlock(&m->lock_);
}
class ThreadBarrierPrivate {
public:
pthread_mutex_t mutex;
pthread_cond_t cond;
int count;
int tripCount;
inline explicit ThreadBarrierPrivate(int cnt):count(0), tripCount(cnt) {
CHECK_NE(cnt, 0);
CHECK_GE(pthread_mutex_init(&mutex, 0), 0);
CHECK_GE(pthread_cond_init(&cond, 0), 0);
}
inline ~ThreadBarrierPrivate() {
pthread_cond_destroy(&cond);
pthread_mutex_destroy(&mutex);
}
/**
* @brief wait
* @return true if the last wait
*/
inline bool wait() {
pthread_mutex_lock(&mutex);
++count;
if (count > tripCount) {
count = 0;
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);
return true;
} else {
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
return false;
}
}
};
ThreadBarrier::ThreadBarrier(int count): m(new ThreadBarrierPrivate(count)) {}
ThreadBarrier::~ThreadBarrier() { delete m; }
void ThreadBarrier::wait() { m->wait(); }
} // namespace paddle
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册