diff options
author | bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-05-14 14:09:24 +0000 |
---|---|---|
committer | bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-05-14 14:09:24 +0000 |
commit | 554875210043b34178f7ed6ac5bd682b1fad367b (patch) | |
tree | fdadeb167ef502f98784117a3c05378c72fceeec /src/utils/SkThreadUtils_pthread.cpp | |
parent | f105b109264f71dfb0bfd9977e6a5dd0a5a12f57 (diff) |
Add bench and test for SkRefCnt.
http://codereview.appspot.com/6195071/
This also adds a cross platform SkThread for testing purposes.
git-svn-id: http://skia.googlecode.com/svn/trunk@3921 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/utils/SkThreadUtils_pthread.cpp')
-rw-r--r-- | src/utils/SkThreadUtils_pthread.cpp | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/utils/SkThreadUtils_pthread.cpp b/src/utils/SkThreadUtils_pthread.cpp new file mode 100644 index 0000000000..17a2075ab0 --- /dev/null +++ b/src/utils/SkThreadUtils_pthread.cpp @@ -0,0 +1,105 @@ +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkTypes.h" + +#include "SkThreadUtils.h" +#include "SkThreadUtils_pthread.h" + +#include <pthread.h> +#include <signal.h> + +SkThread_PThreadData::SkThread_PThreadData(SkThread::entryPointProc entryPoint, void* data) + : fPThread() + , fValidPThread(false) + , fParam(data) + , fEntryPoint(entryPoint) + , fStarted(false) +{ + pthread_mutex_init(&fStartMutex, NULL); + + pthread_cond_init(&fStartCondition, NULL); + + pthread_attr_init(&fAttr); + pthread_attr_setdetachstate(&fAttr, PTHREAD_CREATE_JOINABLE); +} +SkThread_PThreadData::~SkThread_PThreadData() { + pthread_attr_destroy(&fAttr); + pthread_cond_destroy(&fStartCondition); + pthread_mutex_destroy(&fStartMutex); +} + +static void* thread_start(void* arg) { + SkThread_PThreadData* pthreadData = static_cast<SkThread_PThreadData*>(arg); + //Wait for start signal + pthread_mutex_lock(&(pthreadData->fStartMutex)); + while (!pthreadData->fStarted) { + pthread_cond_wait(&(pthreadData->fStartCondition), &(pthreadData->fStartMutex)); + } + pthread_mutex_unlock(&(pthreadData->fStartMutex)); + + //See if this thread was canceled before starting. + pthread_testcancel(); + + pthreadData->fEntryPoint(pthreadData->fParam); + return NULL; +} + +SkThread::SkThread(entryPointProc entryPoint, void* data) { + SkThread_PThreadData* pthreadData = new SkThread_PThreadData(entryPoint, data); + fData = pthreadData; + + int ret = pthread_create(&(pthreadData->fPThread), + &(pthreadData->fAttr), + thread_start, + pthreadData); + + pthreadData->fValidPThread = (0 == ret); +} + +SkThread::~SkThread() { + if (fData != NULL) { + SkThread_PThreadData* pthreadData = static_cast<SkThread_PThreadData*>(fData); + // If created thread but start was never called, kill the thread. + if (pthreadData->fValidPThread && !pthreadData->fStarted) { + if (pthread_cancel(pthreadData->fPThread) == 0) { + if (this->start()) { + this->join(); + } + } else { + //kill with prejudice + pthread_kill(pthreadData->fPThread, SIGKILL); + } + } + delete pthreadData; + } +} + +bool SkThread::start() { + SkThread_PThreadData* pthreadData = static_cast<SkThread_PThreadData*>(fData); + if (!pthreadData->fValidPThread) { + return false; + } + + if (pthreadData->fStarted) { + return false; + } + pthreadData->fStarted = true; + pthread_mutex_lock(&(pthreadData->fStartMutex)); + pthread_cond_signal(&(pthreadData->fStartCondition)); + pthread_mutex_unlock(&(pthreadData->fStartMutex)); + return true; +} + +void SkThread::join() { + SkThread_PThreadData* pthreadData = static_cast<SkThread_PThreadData*>(fData); + if (!pthreadData->fValidPThread || !pthreadData->fStarted) { + return; + } + + pthread_join(pthreadData->fPThread, NULL); +} |