mirror of
https://gitee.com/openharmony/resourceschedule_ffrt
synced 2024-12-02 10:26:58 +00:00
ffrt mutex/recursive_mutex api normalization
Signed-off-by: yuanzhipu <2710242656@qq.com>
This commit is contained in:
parent
b92ceb53c8
commit
36663943b6
@ -2451,6 +2451,18 @@ typedef enum {
|
||||
|
||||
struct ffrt_mutex_t;
|
||||
|
||||
struct ffrt_mutexattr_t;
|
||||
|
||||
typedef enum {
|
||||
ffrt_mutex_normal = PTHREAD_MUTEX_NORMAL,
|
||||
ffrt_mutex_recursive = PTHREAD_MUTEX_RECURSIVE,
|
||||
ffrt_mutex_default = ffrt_mutex_normal
|
||||
} ffrt_mutex_type;
|
||||
|
||||
int ffrt_mutexattr_init(ffrt_mutexattr_t* attr);
|
||||
int ffrt_mutexattr_settype(ffrt_mutexattr_t* attr, int type);
|
||||
int ffrt_mutexattr_gettype(ffrt_mutexattr_t* attr, int* type);
|
||||
int ffrt_mutexattr_destroy(ffrt_mutexattr_t* attr);
|
||||
int ffrt_mutex_init(ffrt_mutex_t* mutex, const ffrt_mutexattr_t* attr);
|
||||
int ffrt_mutex_lock(ffrt_mutex_t* mutex);
|
||||
int ffrt_mutex_unlock(ffrt_mutex_t* mutex);
|
||||
@ -2459,14 +2471,17 @@ int ffrt_mutex_destroy(ffrt_mutex_t* mutex);
|
||||
```
|
||||
|
||||
#### 参数
|
||||
`type`
|
||||
|
||||
* FFRT锁类型,当前仅支持互斥锁ffrt_mutex_normal和递归锁ffrt_mutex_recursive
|
||||
|
||||
`attr`
|
||||
|
||||
* 当前FFRT只支持基础类型的mutex,因此attr必须为空指针
|
||||
* FFRT锁属性,attr如果为空指针代表互斥锁mutex
|
||||
|
||||
`mutex`
|
||||
|
||||
* 指向所操作的互斥锁的指针
|
||||
* 指向所操作的锁指针
|
||||
|
||||
#### 返回值
|
||||
|
||||
@ -2475,9 +2490,12 @@ int ffrt_mutex_destroy(ffrt_mutex_t* mutex);
|
||||
#### 描述
|
||||
* 该接口只能在FFRT task 内部调用,在FFRT task 外部调用存在未定义的行为
|
||||
* 该功能能够避免pthread传统的pthread_mutex_t 在抢不到锁时陷入内核的问题,在使用得当的条件下将会有更好的性能
|
||||
* **注意:目前暂不支持递归和定时功能**
|
||||
* **注意:目前暂不支持定时功能**
|
||||
* **注意:C API中的ffrt_mutexattr_t需要用户调用`ffrt_mutexattr_init`和`ffrt_mutexattr_destroy`显示创建和销毁,而C++ API无需该操作**
|
||||
* **注意:C API中的ffrt_mutex_t需要用户调用`ffrt_mutex_init`和`ffrt_mutex_destroy`显式创建和销毁,而C++ API无需该操作**
|
||||
* **注意:C API中的ffrt_mutex_t对象的置空和销毁由用户完成,对同一个ffrt_mutex_t仅能调用一次`ffrt_mutex_destroy`,重复对同一个ffrt_mutex_t调用`ffrt_mutex_destroy`,其行为是未定义的**
|
||||
* **注意:C API中的同一个ffrt_mutexattr_t只能调用一次`ffrt_mutexattr_init`和`ffrt_mutexattr_destroy`,重复调用其行为是未定义的**
|
||||
* **注意:用户需要在调用`ffrt_mutex_init`之后和调用`ffrt_mutex_destroy`之前显示调用`ffrt_mutexattr_destroy`**
|
||||
* **注意:在`ffrt_mutex_destroy`之后再对ffrt_mutex_t进行访问,其行为是未定义的**
|
||||
|
||||
#### 样例
|
||||
@ -2567,11 +2585,43 @@ void ffrt_mutex_task()
|
||||
printf("sum = %d", sum);
|
||||
}
|
||||
|
||||
void ffrt_recursive_mutex_task()
|
||||
{
|
||||
int sum = 0;
|
||||
int ret = 0;
|
||||
ffrt_mutexattr_t attr;
|
||||
ffrt_mutex_t mtx;
|
||||
ret = ffrt_mutexattr_init(&attr);
|
||||
if (ret != ffrt_success) {
|
||||
printf("mutexattr init error\n");
|
||||
}
|
||||
ret = ffrt_mutexattr_settype(&attr, ffrt_mutex_recursive);
|
||||
if (ret != ffrt_success) {
|
||||
printf("mutexattr settype error\n");
|
||||
}
|
||||
tuple t = {&sum, &mtx};
|
||||
int ret = ffrt_mutex_init(&mtx, &attr);
|
||||
if (ret != ffrt_success) {
|
||||
printf("error\n");
|
||||
}
|
||||
for (int i = 0; i < 10; i++) {
|
||||
ffrt_submit_c(func, NULL, &t, NULL, NULL, NULL);
|
||||
}
|
||||
ffrt_mutexattr_destory(&attr);
|
||||
ffrt_mutex_destroy(&mtx);
|
||||
ffrt_wait();
|
||||
printf("sum = %d", sum);
|
||||
}
|
||||
|
||||
int main(int narg, char** argv)
|
||||
{
|
||||
int r;
|
||||
/* mutex */
|
||||
ffrt_submit_c(ffrt_mutex_task, NULL, NULL, NULL, NULL, NULL);
|
||||
ffrt_wait();
|
||||
/* recursive mutex */
|
||||
ffrt_submit_c(ffrt_recursive_mutex_task, NULL, NULL, NULL, NULL, NULL);
|
||||
ffrt_wait();
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
@ -38,6 +38,53 @@
|
||||
#define FFRT_API_C_MUTEX_H
|
||||
#include "type_def.h"
|
||||
|
||||
/**
|
||||
* @brief Initializes mutex attr.
|
||||
*
|
||||
* @param mutex Indicates a pointer to the mutex.
|
||||
* @param attr Indicates a pointer to the mutex attribute.
|
||||
* @return Returns <b>ffrt_thrd_success</b> if the mutexattr is initialized;
|
||||
returns <b>ffrt_thrd_error</b> otherwise.
|
||||
* @since 12
|
||||
* @version 1.0
|
||||
*/
|
||||
FFRT_C_API int ffrt_mutexattr_init(ffrt_mutexattr_t* attr);
|
||||
|
||||
/**
|
||||
* @brief set mutex type.
|
||||
*
|
||||
* @param attr Indicates a pointer to the mutex attribute.
|
||||
* @param type Indicates a int to the mutex type.
|
||||
* @return Returns <b>ffrt_thrd_success</b> if the mutexattr type is set;
|
||||
returns <b>ffrt_thrd_error</b> otherwise.
|
||||
* @since 12
|
||||
* @version 1.0
|
||||
*/
|
||||
FFRT_C_API int ffrt_mutexattr_settype(ffrt_mutexattr_t* attr, int type);
|
||||
|
||||
/**
|
||||
* @brief get mutex type.
|
||||
*
|
||||
* @param attr Indicates a pointer to the mutex attribute.
|
||||
* @param type Indicates a pointer to the mutex type.
|
||||
* @return Returns <b>ffrt_thrd_success</b> if the mutexattr is initialized;
|
||||
returns <b>ffrt_thrd_error</b> otherwise.
|
||||
* @since 12
|
||||
* @version 1.0
|
||||
*/
|
||||
FFRT_C_API int ffrt_mutexattr_gettype(ffrt_mutexattr_t* attr, int* type);
|
||||
|
||||
/**
|
||||
* @brief destroy mutex attr, the user needs to invoke this interface.
|
||||
*
|
||||
* @param attr Indicates a pointer to the mutex attribute.
|
||||
* @return Returns <b>ffrt_thrd_success</b> if the mutexattr is destroyed;
|
||||
returns <b>ffrt_thrd_error</b> otherwise.
|
||||
* @since 12
|
||||
* @version 1.0
|
||||
*/
|
||||
FFRT_C_API int ffrt_mutexattr_destroy(ffrt_mutexattr_t* attr);
|
||||
|
||||
/**
|
||||
* @brief Initializes a mutex.
|
||||
*
|
||||
@ -93,60 +140,4 @@ FFRT_C_API int ffrt_mutex_trylock(ffrt_mutex_t* mutex);
|
||||
* @version 1.0
|
||||
*/
|
||||
FFRT_C_API int ffrt_mutex_destroy(ffrt_mutex_t* mutex);
|
||||
|
||||
/**
|
||||
* @brief Initializes a recursive mutex.
|
||||
*
|
||||
* @param mutex Indicates a pointer to the mutex.
|
||||
* @param attr Indicates a pointer to the mutex attribute.
|
||||
* @return Returns <b>ffrt_thrd_success</b> if the mutex is initialized;
|
||||
returns <b>ffrt_thrd_error</b> otherwise.
|
||||
* @since 10
|
||||
* @version 1.0
|
||||
*/
|
||||
FFRT_C_API int ffrt_recursive_mutex_init(ffrt_mutex_t* mutex, const ffrt_mutexattr_t* attr);
|
||||
|
||||
/**
|
||||
* @brief Locks a recursive mutex.
|
||||
*
|
||||
* @param mutex Indicates a pointer to the mutex.
|
||||
* @return Returns <b>ffrt_thrd_success</b> if the mutex is locked;
|
||||
returns <b>ffrt_thrd_error</b> or blocks the calling thread otherwise.
|
||||
* @since 10
|
||||
* @version 1.0
|
||||
*/
|
||||
FFRT_C_API int ffrt_recursive_mutex_lock(ffrt_mutex_t* mutex);
|
||||
|
||||
/**
|
||||
* @brief Unlocks a recursive mutex.
|
||||
*
|
||||
* @param mutex Indicates a pointer to the mutex.
|
||||
* @return Returns <b>ffrt_thrd_success</b> if the mutex is unlocked;
|
||||
returns <b>ffrt_thrd_error</b> otherwise.
|
||||
* @since 10
|
||||
* @version 1.0
|
||||
*/
|
||||
FFRT_C_API int ffrt_recursive_mutex_unlock(ffrt_mutex_t* mutex);
|
||||
|
||||
/**
|
||||
* @brief Attempts to lock a recursive mutex.
|
||||
*
|
||||
* @param mutex Indicates a pointer to the mutex.
|
||||
* @return Returns <b>ffrt_thrd_success</b> if the mutex is locked;
|
||||
returns <b>ffrt_thrd_error</b> or <b>ffrt_thrd_busy</b> otherwise.
|
||||
* @since 10
|
||||
* @version 1.0
|
||||
*/
|
||||
FFRT_C_API int ffrt_recursive_mutex_trylock(ffrt_mutex_t* mutex);
|
||||
|
||||
/**
|
||||
* @brief Destroys a recursive mutex.
|
||||
*
|
||||
* @param mutex Indicates a pointer to the mutex.
|
||||
* @return Returns <b>ffrt_thrd_success</b> if the mutex is destroyed;
|
||||
returns <b>ffrt_thrd_error</b> otherwise.
|
||||
* @since 10
|
||||
* @version 1.0
|
||||
*/
|
||||
FFRT_C_API int ffrt_recursive_mutex_destroy(ffrt_mutex_t* mutex);
|
||||
#endif
|
||||
|
@ -37,6 +37,7 @@
|
||||
*/
|
||||
#ifndef FFRT_API_C_TYPE_DEF_H
|
||||
#define FFRT_API_C_TYPE_DEF_H
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
@ -183,6 +184,12 @@ typedef struct {
|
||||
long storage;
|
||||
} ffrt_mutexattr_t;
|
||||
|
||||
typedef enum {
|
||||
ffrt_mutex_normal = PTHREAD_MUTEX_NORMAL,
|
||||
ffrt_mutex_recursive = PTHREAD_MUTEX_RECURSIVE,
|
||||
ffrt_mutex_default = ffrt_mutex_normal
|
||||
} ffrt_mutex_type;
|
||||
|
||||
typedef struct {
|
||||
uint32_t storage[(ffrt_mutex_storage_size + sizeof(uint32_t) - 1) / sizeof(uint32_t)];
|
||||
} ffrt_mutex_t;
|
||||
|
@ -61,11 +61,14 @@ class recursive_mutex : public ffrt_mutex_t {
|
||||
public:
|
||||
recursive_mutex()
|
||||
{
|
||||
ffrt_recursive_mutex_init(this, nullptr);
|
||||
ffrt_mutexattr_init(&attr);
|
||||
ffrt_mutexattr_settype(&attr, ffrt_mutex_recursive);
|
||||
ffrt_recursive_mutex_init(this, &attr);
|
||||
}
|
||||
|
||||
~recursive_mutex()
|
||||
{
|
||||
ffrt_mutexattr_destroy(&attr);
|
||||
ffrt_recursive_mutex_destroy(this);
|
||||
}
|
||||
|
||||
@ -74,18 +77,20 @@ public:
|
||||
|
||||
inline bool try_lock()
|
||||
{
|
||||
return ffrt_recursive_mutex_trylock(this) == ffrt_success ? true : false;
|
||||
return ffrt_mutex_trylock(this) == ffrt_success ? true : false;
|
||||
}
|
||||
|
||||
inline void lock()
|
||||
{
|
||||
ffrt_recursive_mutex_lock(this);
|
||||
ffrt_mutex_lock(this);
|
||||
}
|
||||
|
||||
inline void unlock()
|
||||
{
|
||||
ffrt_recursive_mutex_unlock(this);
|
||||
ffrt_mutex_unlock(this);
|
||||
}
|
||||
private:
|
||||
ffrt_mutexattr_t attr;
|
||||
};
|
||||
} // namespace ffrt
|
||||
#endif
|
||||
|
@ -280,6 +280,53 @@ void mutexPrivate::wake()
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
API_ATTRIBUTE((visibility("default")))
|
||||
int ffrt_mutexattr_init(ffrt_mutexattr_t* attr)
|
||||
{
|
||||
if (attr == nullptr) {
|
||||
FFRT_LOGE("attr should not be empty");
|
||||
return ffrt_error_inval;
|
||||
}
|
||||
attr->storage = static_cast<long>(ffrt_mutex_dafault);
|
||||
return ffrt_success;
|
||||
}
|
||||
|
||||
API_ATTRIBUTE((visibility("default")))
|
||||
int ffrt_mutexattr_settype(ffrt_mutexattr_t* attr, int type)
|
||||
{
|
||||
if (attr == nullptr) {
|
||||
FFRT_LOGE("attr should not be empty");
|
||||
return ffrt_error_inval;
|
||||
}
|
||||
if (type != ffrt_mutex_normal && type != ffrt_mutex_recursive && type != ffrt_mutex_default) {
|
||||
FFRT_LOGE("mutex type is invaild");
|
||||
return ffrt_error_inval;
|
||||
}
|
||||
attr->storage = static_cast<long>(type);
|
||||
return ffrt_success;
|
||||
}
|
||||
|
||||
API_ATTRIBUTE((visibility("default")))
|
||||
int ffrt_mutexattr_gettype(ffrt_mutexattr_t* attr, int* type)
|
||||
{
|
||||
if (attr == nullptr || type == nullptr) {
|
||||
FFRT_LOGE("attr or type should not be empty");
|
||||
return ffrt_error_inval;
|
||||
}
|
||||
*type = static_cast<int>(attr->storage);
|
||||
return ffrt_success;
|
||||
}
|
||||
|
||||
API_ATTRIBUTE((visibility("default")))
|
||||
int ffrt_mutexattr_destroy(ffrt_mutexattr_t* attr)
|
||||
{
|
||||
if (attr == nullptr) {
|
||||
FFRT_LOGE("attr should not be empty");
|
||||
return ffrt_error_inval;
|
||||
}
|
||||
return ffrt_success;
|
||||
}
|
||||
|
||||
API_ATTRIBUTE((visibility("default")))
|
||||
int ffrt_mutex_init(ffrt_mutex_t* mutex, const ffrt_mutexattr_t* attr)
|
||||
{
|
||||
@ -287,33 +334,18 @@ int ffrt_mutex_init(ffrt_mutex_t* mutex, const ffrt_mutexattr_t* attr)
|
||||
FFRT_LOGE("mutex should not be empty");
|
||||
return ffrt_error_inval;
|
||||
}
|
||||
if (attr != nullptr) {
|
||||
FFRT_LOGE("only support normal mutex");
|
||||
return ffrt_error;
|
||||
}
|
||||
static_assert(sizeof(ffrt::mutexPrivate) <= ffrt_mutex_storage_size,
|
||||
if (attr == nullptr || attr->storage == static_cast<long>(ffrt_mutex_normal)) {
|
||||
static_assert(sizeof(ffrt::mutexPrivate) <= ffrt_mutex_storage_size,
|
||||
"size must be less than ffrt_mutex_storage_size");
|
||||
|
||||
new (mutex)ffrt::mutexPrivate();
|
||||
return ffrt_success;
|
||||
}
|
||||
|
||||
API_ATTRIBUTE((visibility("default")))
|
||||
int ffrt_recursive_mutex_init(ffrt_mutex_t* mutex, const ffrt_mutexattr_t* attr)
|
||||
{
|
||||
if (!mutex) {
|
||||
FFRT_LOGE("mutex should not be empty");
|
||||
return ffrt_error_inval;
|
||||
}
|
||||
if (attr != nullptr) {
|
||||
FFRT_LOGE("only support normal mutex");
|
||||
return ffrt_error;
|
||||
}
|
||||
static_assert(sizeof(ffrt::RecursiveMutexPrivate) <= ffrt_mutex_storage_size,
|
||||
new (mutex)ffrt::mutexPrivate();
|
||||
return ffrt_success;
|
||||
} else if (attr->storage == static_cast<long>(ffrt_mutex_recursive)) {
|
||||
static_assert(sizeof(ffrt::RecursiveMutexPrivate) <= ffrt_mutex_storage_size,
|
||||
"size must be less than ffrt_mutex_storage_size");
|
||||
|
||||
new (mutex)ffrt::RecursiveMutexPrivate();
|
||||
return ffrt_success;
|
||||
new (mutex)ffrt::RecursiveMutexPrivate();
|
||||
return ffrt_success;
|
||||
}
|
||||
return ffrt_error_inval;
|
||||
}
|
||||
|
||||
API_ATTRIBUTE((visibility("default")))
|
||||
@ -323,19 +355,7 @@ int ffrt_mutex_lock(ffrt_mutex_t* mutex)
|
||||
FFRT_LOGE("mutex should not be empty");
|
||||
return ffrt_error_inval;
|
||||
}
|
||||
auto p = reinterpret_cast<ffrt::mutexPrivate*>(mutex);
|
||||
p->lock();
|
||||
return ffrt_success;
|
||||
}
|
||||
|
||||
API_ATTRIBUTE((visibility("default")))
|
||||
int ffrt_recursive_mutex_lock(ffrt_mutex_t* mutex)
|
||||
{
|
||||
if (!mutex) {
|
||||
FFRT_LOGE("mutex should not be empty");
|
||||
return ffrt_error_inval;
|
||||
}
|
||||
auto p = reinterpret_cast<ffrt::RecursiveMutexPrivate*>(mutex);
|
||||
auto p = reinterpret_cast<ffrt::mutexBase*>(mutex);
|
||||
p->lock();
|
||||
return ffrt_success;
|
||||
}
|
||||
@ -347,19 +367,7 @@ int ffrt_mutex_unlock(ffrt_mutex_t* mutex)
|
||||
FFRT_LOGE("mutex should not be empty");
|
||||
return ffrt_error_inval;
|
||||
}
|
||||
auto p = reinterpret_cast<ffrt::mutexPrivate*>(mutex);
|
||||
p->unlock();
|
||||
return ffrt_success;
|
||||
}
|
||||
|
||||
API_ATTRIBUTE((visibility("default")))
|
||||
int ffrt_recursive_mutex_unlock(ffrt_mutex_t* mutex)
|
||||
{
|
||||
if (!mutex) {
|
||||
FFRT_LOGE("mutex should not be empty");
|
||||
return ffrt_error_inval;
|
||||
}
|
||||
auto p = reinterpret_cast<ffrt::RecursiveMutexPrivate*>(mutex);
|
||||
auto p = reinterpret_cast<ffrt::mutexBase*>(mutex);
|
||||
p->unlock();
|
||||
return ffrt_success;
|
||||
}
|
||||
@ -371,18 +379,7 @@ int ffrt_mutex_trylock(ffrt_mutex_t* mutex)
|
||||
FFRT_LOGE("mutex should not be empty");
|
||||
return ffrt_error_inval;
|
||||
}
|
||||
auto p = reinterpret_cast<ffrt::mutexPrivate*>(mutex);
|
||||
return p->try_lock() ? ffrt_success : ffrt_error_busy;
|
||||
}
|
||||
|
||||
API_ATTRIBUTE((visibility("default")))
|
||||
int ffrt_recursive_mutex_trylock(ffrt_mutex_t* mutex)
|
||||
{
|
||||
if (!mutex) {
|
||||
FFRT_LOGE("mutex should not be empty");
|
||||
return ffrt_error_inval;
|
||||
}
|
||||
auto p = reinterpret_cast<ffrt::RecursiveMutexPrivate*>(mutex);
|
||||
auto p = reinterpret_cast<ffrt::mutexBase*>(mutex);
|
||||
return p->try_lock() ? ffrt_success : ffrt_error_busy;
|
||||
}
|
||||
|
||||
@ -393,23 +390,11 @@ int ffrt_mutex_destroy(ffrt_mutex_t* mutex)
|
||||
FFRT_LOGE("mutex should not be empty");
|
||||
return ffrt_error_inval;
|
||||
}
|
||||
auto p = reinterpret_cast<ffrt::mutexPrivate*>(mutex);
|
||||
auto p = reinterpret_cast<ffrt::mutexBase*>(mutex);
|
||||
p->~mutexPrivate();
|
||||
return ffrt_success;
|
||||
}
|
||||
|
||||
API_ATTRIBUTE((visibility("default")))
|
||||
int ffrt_recursive_mutex_destroy(ffrt_mutex_t* mutex)
|
||||
{
|
||||
if (!mutex) {
|
||||
FFRT_LOGE("mutex should not be empty");
|
||||
return ffrt_error_inval;
|
||||
}
|
||||
auto p = reinterpret_cast<ffrt::RecursiveMutexPrivate*>(mutex);
|
||||
p->~RecursiveMutexPrivate();
|
||||
return ffrt_success;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -100,7 +100,16 @@ public:
|
||||
};
|
||||
#endif
|
||||
|
||||
class mutexPrivate {
|
||||
class mutexBase {
|
||||
public:
|
||||
mutexBase() = default;
|
||||
virtual ~mutexBase() = default;
|
||||
virtual void lock() {}
|
||||
virtual void unlock() {}
|
||||
virtual bool try_lock() {return false;}
|
||||
};
|
||||
|
||||
class mutexPrivate : public mutexBase {
|
||||
std::atomic<int> l;
|
||||
#ifdef FFRT_MUTEX_DEADLOCK_CHECK
|
||||
std::atomic<uintptr_t> owner;
|
||||
@ -120,16 +129,16 @@ public:
|
||||
mutexPrivate(mutexPrivate const &) = delete;
|
||||
void operator = (mutexPrivate const &) = delete;
|
||||
|
||||
bool try_lock();
|
||||
void lock();
|
||||
void unlock();
|
||||
bool try_lock() override;
|
||||
void lock() override;
|
||||
void unlock() override;
|
||||
};
|
||||
|
||||
class RecursiveMutexPrivate {
|
||||
class RecursiveMutexPrivate : public mutexBase {
|
||||
public:
|
||||
void lock();
|
||||
void unlock();
|
||||
bool try_lock();
|
||||
void lock() override;
|
||||
void unlock() override;
|
||||
bool try_lock() override;
|
||||
|
||||
RecursiveMutexPrivate() = default;
|
||||
~RecursiveMutexPrivate() = default;
|
||||
|
@ -23,6 +23,10 @@
|
||||
#include "dfx/log/ffrt_log_api.h"
|
||||
#include "c/thread.h"
|
||||
|
||||
extern "C" int ffrt_mutexattr_init(ffrt_mutexattr_t* attr);
|
||||
extern "C" int ffrt_mutexattr_settype(ffrt_mutexattr_t* attr, int type);
|
||||
extern "C" int ffrt_mutexattr_gettype(ffrt_mutexattr_t* attr, int* type);
|
||||
extern "C" int ffrt_mutexattr_destroy(ffrt_mutexattr_t* attr);
|
||||
extern "C" int ffrt_mutex_init(ffrt_mutex_t *mutex, const ffrt_mutexattr_t* attr);
|
||||
extern "C" int ffrt_mutex_lock(ffrt_mutex_t *mutex);
|
||||
extern "C" int ffrt_mutex_unlock(ffrt_mutex_t *mutex);
|
||||
@ -51,6 +55,18 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
HWTEST_F(SyncTest, mutexattr_nullptr_fail, TestSize.Level1)
|
||||
{
|
||||
int ret = ffrt_mutexattr_init(nullptr);
|
||||
EXPECT_EQ(ret, ffrt_error_inval);
|
||||
ret = ffrt_mutexattr_settype(nullptr, 0);
|
||||
EXPECT_EQ(ret, ffrt_error_inval);
|
||||
ret = ffrt_mutexattr_gettype(nullptr, nullptr);
|
||||
EXPECT_EQ(ret, ffrt_error_inval);
|
||||
ret = ffrt_mutexattr_destroy(nullptr);
|
||||
EXPECT_EQ(ret, ffrt_error_inval);
|
||||
}
|
||||
|
||||
HWTEST_F(SyncTest, mutex_nullptr_fail, TestSize.Level1)
|
||||
{
|
||||
int ret = ffrt_mutex_init(nullptr, nullptr);
|
||||
@ -64,6 +80,20 @@ HWTEST_F(SyncTest, mutex_nullptr_fail, TestSize.Level1)
|
||||
ffrt_mutex_destroy(nullptr);
|
||||
}
|
||||
|
||||
HWTEST_F(SyncTest, recursive_mutex_try_lock, TestSize.Level1)
|
||||
{
|
||||
int val = -1;
|
||||
ffrt::recursive_mutex lock;
|
||||
lock.lock();
|
||||
val = lock.try_lock();
|
||||
EXPECT_EQ(val, 1);
|
||||
lock.unlock();
|
||||
val = lock.try_lock();
|
||||
EXPECT_EQ(val, 1);
|
||||
lock.unlock();
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
HWTEST_F(SyncTest, class_data_align, TestSize.Level1)
|
||||
{
|
||||
struct memTest {
|
||||
|
Loading…
Reference in New Issue
Block a user