Files
edgetx-gx12/radio/src/os/task.h
T

121 lines
3.6 KiB
C++

/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#pragma once
#include <stdbool.h>
// OS specific implementation
#if defined(NATIVE_THREADS)
#include "task_native.h"
#elif defined(FREE_RTOS)
#include "task_freertos.h"
#endif
typedef void (*task_func_t)();
void task_create(task_handle_t* h, task_func_t func, const char* name,
void* stack, unsigned stack_size, unsigned priority);
unsigned task_get_stack_usage(task_handle_t* h);
unsigned task_get_stack_size(task_handle_t* h);
bool scheduler_is_running();
void mutex_create(mutex_handle_t* h);
bool mutex_lock(mutex_handle_t* h);
void mutex_unlock(mutex_handle_t* h);
bool mutex_trylock(mutex_handle_t* h);
// this helper class is only to be used on the stack and never to be shared outside the scope where it was created
/* example usage
*
* void doWork()
* {
*
* MutexLock lock = MutexLock::MakeInstance(mutex);
* while(!queue.isEmpty)
* {
* lock.unlock();
* auto item = queue.pop();
* <do something with item>
* lock.lock();
* }
* } // auto mutex unlock, because lock is destructed here
*
* int sendMessage()
* {
* MutexLock lock = MutexLock::MakeInstance(busMutex);
* if(busSendData(...) != OK)
* return ERROR; // auto mutex unlock, because lock is destructed here
*
* lock.unlock();
* <do some other stuff>
* if(<something>)
* return ERROR; // no auto mutex unlock, because already unlocked
* lock.lock()
* if(busSendData(...) != OK)
* return ERROR; // auto mutex unlock, because lock is destructed here
*
* return OK;
* } // auto mutex unlock here, because lock is destructed here
*
* int doSomething()
* {
*
* <code here>
* if(<bus usage condition>)
* {
* MutexLock lock = MutexLock::MakeInstance(busMutex);
* if(busSendData(...) != OK)
* return ERROR; // auto mutex unlock, because lock is destructed here
* } // auto mutex unlock here, because lock is destructed here
*
* <code here>
*
* return OK;
* }
*/
class MutexLock
{
public:
static MutexLock MakeInstance(mutex_handle_t* mtx) {return MutexLock(mtx);}
~MutexLock() {if(!scheduler_is_running()) return; if(locked) mutex_unlock(mutex);}
void lock() {if(!scheduler_is_running()) return; if(!locked) mutex_lock(mutex); locked=true;}
void unlock() {if(!scheduler_is_running()) return; if(locked) mutex_unlock(mutex); locked=false;}
MutexLock(const MutexLock&) = delete;
MutexLock(MutexLock&&) = delete;
MutexLock& operator =(const MutexLock&) = delete;
MutexLock& operator =(MutexLock&&) = delete;
static void* operator new (size_t) = delete;
static void* operator new[] (size_t) = delete;
static void operator delete (void*) = delete;
static void operator delete[](void*) = delete;
private:
MutexLock(mutex_handle_t* mtx):mutex(mtx),locked(false) {if(!scheduler_is_running()) return; mutex_lock(mutex); locked = true;}
mutex_handle_t* mutex;
bool locked;
};