mirror of
https://github.com/LineageOS/android_device_xiaomi_whyred.git
synced 2025-10-03 17:59:24 +02:00
whyred: Import gps from LA.UM.6.2.r2-03600-sdm660.0
This commit is contained in:
parent
d7699194e4
commit
00cbc6eba8
142 changed files with 30786 additions and 0 deletions
266
gps/utils/LocThread.cpp
Normal file
266
gps/utils/LocThread.cpp
Normal file
|
@ -0,0 +1,266 @@
|
|||
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation, nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <LocThread.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <platform_lib_macros.h>
|
||||
|
||||
class LocThreadDelegate {
|
||||
LocRunnable* mRunnable;
|
||||
bool mJoinable;
|
||||
pthread_t mThandle;
|
||||
pthread_mutex_t mMutex;
|
||||
int mRefCount;
|
||||
~LocThreadDelegate();
|
||||
LocThreadDelegate(LocThread::tCreate creator, const char* threadName,
|
||||
LocRunnable* runnable, bool joinable);
|
||||
void destroy();
|
||||
public:
|
||||
static LocThreadDelegate* create(LocThread::tCreate creator,
|
||||
const char* threadName, LocRunnable* runnable, bool joinable);
|
||||
void stop();
|
||||
// bye() is for the parent thread to go away. if joinable,
|
||||
// parent must stop the spawned thread, join, and then
|
||||
// destroy(); if detached, the parent can go straight
|
||||
// ahead to destroy()
|
||||
inline void bye() { mJoinable ? stop() : destroy(); }
|
||||
inline bool isRunning() { return (NULL != mRunnable); }
|
||||
static void* threadMain(void* arg);
|
||||
};
|
||||
|
||||
// it is important to note that internal members must be
|
||||
// initialized to values as if pthread_create succeeds.
|
||||
// This is to avoid the race condition between the threads,
|
||||
// once the thread is created, some of these values will
|
||||
// be check in the spawned thread, and must set correctly
|
||||
// then and there.
|
||||
// However, upon pthread_create failure, the data members
|
||||
// must be set to indicate failure, e.g. mRunnable, and
|
||||
// threashold approprietly for destroy(), e.g. mRefCount.
|
||||
LocThreadDelegate::LocThreadDelegate(LocThread::tCreate creator,
|
||||
const char* threadName, LocRunnable* runnable, bool joinable) :
|
||||
mRunnable(runnable), mJoinable(joinable), mThandle((pthread_t)NULL),
|
||||
mMutex(PTHREAD_MUTEX_INITIALIZER), mRefCount(2) {
|
||||
|
||||
// set up thread name, if nothing is passed in
|
||||
if (!threadName) {
|
||||
threadName = "LocThread";
|
||||
}
|
||||
|
||||
// create the thread here, then if successful
|
||||
// and a name is given, we set the thread name
|
||||
if (creator) {
|
||||
mThandle = creator(threadName, threadMain, this);
|
||||
} else if (pthread_create(&mThandle, NULL, threadMain, this)) {
|
||||
// pthread_create() failed
|
||||
mThandle = (pthread_t)NULL;
|
||||
}
|
||||
|
||||
if (mThandle) {
|
||||
// set thread name
|
||||
char lname[16];
|
||||
int len = (sizeof(lname)>sizeof(threadName)) ?
|
||||
(sizeof(threadName) -1):(sizeof(lname) - 1);
|
||||
memcpy(lname, threadName, len);
|
||||
lname[len] = 0;
|
||||
// set the thread name here
|
||||
pthread_setname_np(mThandle, lname);
|
||||
|
||||
// detach, if not joinable
|
||||
if (!joinable) {
|
||||
pthread_detach(mThandle);
|
||||
}
|
||||
} else {
|
||||
// must set these values upon failure
|
||||
mRunnable = NULL;
|
||||
mJoinable = false;
|
||||
mRefCount = 1;
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
LocThreadDelegate::~LocThreadDelegate() {
|
||||
// at this point nothing should need done any more
|
||||
}
|
||||
|
||||
// factory method so that we could return NULL upon failure
|
||||
LocThreadDelegate* LocThreadDelegate::create(LocThread::tCreate creator,
|
||||
const char* threadName, LocRunnable* runnable, bool joinable) {
|
||||
LocThreadDelegate* thread = NULL;
|
||||
if (runnable) {
|
||||
thread = new LocThreadDelegate(creator, threadName, runnable, joinable);
|
||||
if (thread && !thread->isRunning()) {
|
||||
thread->destroy();
|
||||
thread = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
// The order is importang
|
||||
// NULLing mRunnalbe stops the while loop in threadMain()
|
||||
// join() if mJoinble must come before destroy() call, as
|
||||
// the obj must remain alive at this time so that mThandle
|
||||
// remains valud.
|
||||
void LocThreadDelegate::stop() {
|
||||
// mRunnable and mJoinable are reset on different triggers.
|
||||
// mRunnable may get nulled on the spawned thread's way out;
|
||||
// or here.
|
||||
// mJouinable (if ever been true) gets falsed when client
|
||||
// thread triggers stop, with either a stop()
|
||||
// call or the client releases thread obj handle.
|
||||
if (mRunnable) {
|
||||
mRunnable = NULL;
|
||||
}
|
||||
if (mJoinable) {
|
||||
mJoinable = false;
|
||||
pthread_join(mThandle, NULL);
|
||||
}
|
||||
// call destroy() to possibly delete the obj
|
||||
destroy();
|
||||
}
|
||||
|
||||
// method for clients to call to release the obj
|
||||
// when it is a detached thread, the client thread
|
||||
// and the spawned thread can both try to destroy()
|
||||
// asynchronously. And we delete this obj when
|
||||
// mRefCount becomes 0.
|
||||
void LocThreadDelegate::destroy() {
|
||||
// else case shouldn't happen, unless there is a
|
||||
// leaking obj. But only our code here has such
|
||||
// obj, so if we test our code well, else case
|
||||
// will never happen
|
||||
if (mRefCount > 0) {
|
||||
// we need a flag on the stack
|
||||
bool callDelete = false;
|
||||
|
||||
// critical section between threads
|
||||
pthread_mutex_lock(&mMutex);
|
||||
// last destroy() call
|
||||
callDelete = (1 == mRefCount--);
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
|
||||
// upon last destroy() call we delete this obj
|
||||
if (callDelete) {
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void* LocThreadDelegate::threadMain(void* arg) {
|
||||
LocThreadDelegate* locThread = (LocThreadDelegate*)(arg);
|
||||
|
||||
if (locThread) {
|
||||
LocRunnable* runnable = locThread->mRunnable;
|
||||
|
||||
if (runnable) {
|
||||
if (locThread->isRunning()) {
|
||||
runnable->prerun();
|
||||
}
|
||||
|
||||
while (locThread->isRunning() && runnable->run());
|
||||
|
||||
if (locThread->isRunning()) {
|
||||
runnable->postrun();
|
||||
}
|
||||
|
||||
// at this time, locThread->mRunnable may or may not be NULL
|
||||
// NULL it just to be safe and clean, as we want the field
|
||||
// in the released memory slot to be NULL.
|
||||
locThread->mRunnable = NULL;
|
||||
delete runnable;
|
||||
}
|
||||
locThread->destroy();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LocThread::~LocThread() {
|
||||
if (mThread) {
|
||||
mThread->bye();
|
||||
mThread = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool LocThread::start(tCreate creator, const char* threadName, LocRunnable* runnable, bool joinable) {
|
||||
bool success = false;
|
||||
if (!mThread) {
|
||||
mThread = LocThreadDelegate::create(creator, threadName, runnable, joinable);
|
||||
// true only if thread is created successfully
|
||||
success = (NULL != mThread);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void LocThread::stop() {
|
||||
if (mThread) {
|
||||
mThread->stop();
|
||||
mThread = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __LOC_DEBUG__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
class LocRunnableTest1 : public LocRunnable {
|
||||
int mID;
|
||||
public:
|
||||
LocRunnableTest1(int id) : LocRunnable(), mID(id) {}
|
||||
virtual bool run() {
|
||||
printf("LocRunnableTest1: %d\n", mID++);
|
||||
sleep(1);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// on linux command line:
|
||||
// compile: g++ -D__LOC_HOST_DEBUG__ -D__LOC_DEBUG__ -g -std=c++0x -I. -I../../../../vendor/qcom/proprietary/gps-internal/unit-tests/fakes_for_host -I../../../../system/core/include -lpthread LocThread.cpp
|
||||
// test detached thread: valgrind ./a.out 0
|
||||
// test joinable thread: valgrind ./a.out 1
|
||||
int main(int argc, char** argv) {
|
||||
LocRunnableTest1 test(10);
|
||||
|
||||
LocThread thread;
|
||||
thread.start("LocThreadTest", test, atoi(argv[1]));
|
||||
|
||||
sleep(10);
|
||||
|
||||
thread.stop();
|
||||
|
||||
sleep(5);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue