1570af302Sopenharmony_ci/* 2570af302Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. 3570af302Sopenharmony_ci */ 4570af302Sopenharmony_ci/* 5570af302Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 6570af302Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 7570af302Sopenharmony_ci * you may not use this file except in compliance with the License. 8570af302Sopenharmony_ci * You may obtain a copy of the License at 9570af302Sopenharmony_ci * 10570af302Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 11570af302Sopenharmony_ci * 12570af302Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 13570af302Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 14570af302Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15570af302Sopenharmony_ci * See the License for the specific language governing permissions and 16570af302Sopenharmony_ci * limitations under the License. 17570af302Sopenharmony_ci */ 18570af302Sopenharmony_ci 19570af302Sopenharmony_ci#include <signal.h> 20570af302Sopenharmony_ci#include <stdlib.h> 21570af302Sopenharmony_ci#include <threads.h> 22570af302Sopenharmony_ci#include <pthread.h> 23570af302Sopenharmony_ci#include <stdio.h> 24570af302Sopenharmony_ci#include <time.h> 25570af302Sopenharmony_ci#include <errno.h> 26570af302Sopenharmony_ci#include "test.h" 27570af302Sopenharmony_ci 28570af302Sopenharmony_ci#define LOCK_SUCCESS (0) 29570af302Sopenharmony_ci#define LOCK_TIMEOUT (-1) 30570af302Sopenharmony_ci#define LOCK_WAIT_MAX_TIME_COUNT (50) 31570af302Sopenharmony_ci#define NSEC_TO_MS (1000000) 32570af302Sopenharmony_ci#define TRYLOCK_FAIL (-2) 33570af302Sopenharmony_ci 34570af302Sopenharmony_cistatic thrd_t thr; 35570af302Sopenharmony_cistatic int count = 0; 36570af302Sopenharmony_cipthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; 37570af302Sopenharmony_ci 38570af302Sopenharmony_ciint TrylockWithTimeout(pthread_mutex_t *mutex) 39570af302Sopenharmony_ci{ 40570af302Sopenharmony_ci int rc; 41570af302Sopenharmony_ci 42570af302Sopenharmony_ci int sleepCount = 0; 43570af302Sopenharmony_ci 44570af302Sopenharmony_ci do { 45570af302Sopenharmony_ci rc = pthread_mutex_trylock(mutex); 46570af302Sopenharmony_ci if (rc == 0) { 47570af302Sopenharmony_ci return LOCK_SUCCESS; 48570af302Sopenharmony_ci } else if (rc != EBUSY) { 49570af302Sopenharmony_ci perror("pthread_mutex_trylock"); 50570af302Sopenharmony_ci return TRYLOCK_FAIL; 51570af302Sopenharmony_ci } 52570af302Sopenharmony_ci 53570af302Sopenharmony_ci struct timespec req = { .tv_sec = 0, .tv_nsec = NSEC_TO_MS * 10 }; // 等待10毫秒 54570af302Sopenharmony_ci nanosleep(&req, NULL); 55570af302Sopenharmony_ci 56570af302Sopenharmony_ci sleepCount++; 57570af302Sopenharmony_ci if (sleepCount >= LOCK_WAIT_MAX_TIME_COUNT) { 58570af302Sopenharmony_ci return LOCK_TIMEOUT; 59570af302Sopenharmony_ci } 60570af302Sopenharmony_ci } while (1); 61570af302Sopenharmony_ci} 62570af302Sopenharmony_ci 63570af302Sopenharmony_ciint threadfuncA(void *arg) 64570af302Sopenharmony_ci{ 65570af302Sopenharmony_ci pthread_mutex_t *mtx = (pthread_mutex_t *)arg; 66570af302Sopenharmony_ci pthread_mutex_lock(mtx); 67570af302Sopenharmony_ci count++; 68570af302Sopenharmony_ci thrd_t id = thrd_current(); 69570af302Sopenharmony_ci if (!(thrd_equal(id, thr))) { 70570af302Sopenharmony_ci t_error("%s thrd_current failed", __func__); 71570af302Sopenharmony_ci } 72570af302Sopenharmony_ci pthread_mutex_unlock(mtx); 73570af302Sopenharmony_ci thrd_exit(thrd_success); 74570af302Sopenharmony_ci} 75570af302Sopenharmony_ci 76570af302Sopenharmony_ciint threadfuncB(void *arg) 77570af302Sopenharmony_ci{ 78570af302Sopenharmony_ci int result = TrylockWithTimeout(&g_mutex); 79570af302Sopenharmony_ci if (result == LOCK_SUCCESS) { 80570af302Sopenharmony_ci count++; 81570af302Sopenharmony_ci pthread_mutex_unlock(&g_mutex); 82570af302Sopenharmony_ci } else if (result == LOCK_TIMEOUT) { 83570af302Sopenharmony_ci t_error("Lock acquisition timed out.\n"); 84570af302Sopenharmony_ci } else { 85570af302Sopenharmony_ci t_error("Error pthread_mutex_trylock.\n"); 86570af302Sopenharmony_ci } 87570af302Sopenharmony_ci 88570af302Sopenharmony_ci thrd_exit(thrd_success); 89570af302Sopenharmony_ci} 90570af302Sopenharmony_ci 91570af302Sopenharmony_ci/** 92570af302Sopenharmony_ci * @tc.name : thrd_equal_0100 93570af302Sopenharmony_ci * @tc.desc : Test that two threads have the same ID 94570af302Sopenharmony_ci * @tc.level : Level 0 95570af302Sopenharmony_ci */ 96570af302Sopenharmony_civoid thrd_equal_0100(void) 97570af302Sopenharmony_ci{ 98570af302Sopenharmony_ci int result; 99570af302Sopenharmony_ci pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; 100570af302Sopenharmony_ci pthread_mutex_lock(&mtx); 101570af302Sopenharmony_ci result = thrd_create(&thr, threadfuncA, (void *)&mtx); 102570af302Sopenharmony_ci pthread_mutex_unlock(&mtx); 103570af302Sopenharmony_ci pthread_mutex_destroy(&mtx); 104570af302Sopenharmony_ci if (result != thrd_success) { 105570af302Sopenharmony_ci t_error("%s thrd_create failed", __func__); 106570af302Sopenharmony_ci } 107570af302Sopenharmony_ci 108570af302Sopenharmony_ci result = thrd_sleep(&(struct timespec){.tv_sec = 1}, NULL); 109570af302Sopenharmony_ci if (result != 0) { 110570af302Sopenharmony_ci t_error("%s thrd_sleep failed", __func__); 111570af302Sopenharmony_ci } 112570af302Sopenharmony_ci 113570af302Sopenharmony_ci result = thrd_join(thr, NULL); 114570af302Sopenharmony_ci if (result != thrd_success) { 115570af302Sopenharmony_ci t_error("%s thrd_join failed", __func__); 116570af302Sopenharmony_ci } 117570af302Sopenharmony_ci 118570af302Sopenharmony_ci if (count != 1) { 119570af302Sopenharmony_ci t_error("%s failed, count is %d", __func__, count); 120570af302Sopenharmony_ci } 121570af302Sopenharmony_ci count = 0; 122570af302Sopenharmony_ci} 123570af302Sopenharmony_ci 124570af302Sopenharmony_ci/** 125570af302Sopenharmony_ci * @tc.name : thrd_equal_0200 126570af302Sopenharmony_ci * @tc.desc : Test that two threads have different ID 127570af302Sopenharmony_ci * @tc.level : Level 1 128570af302Sopenharmony_ci */ 129570af302Sopenharmony_civoid thrd_equal_0200(void) 130570af302Sopenharmony_ci{ 131570af302Sopenharmony_ci thrd_t thr1, thr2; 132570af302Sopenharmony_ci int result; 133570af302Sopenharmony_ci 134570af302Sopenharmony_ci result = thrd_create(&thr1, threadfuncB, NULL); 135570af302Sopenharmony_ci if (result != thrd_success) { 136570af302Sopenharmony_ci t_error("%s thrd_create failed", __func__); 137570af302Sopenharmony_ci } 138570af302Sopenharmony_ci 139570af302Sopenharmony_ci result = thrd_create(&thr2, threadfuncB, NULL); 140570af302Sopenharmony_ci if (result != thrd_success) { 141570af302Sopenharmony_ci t_error("%s thrd_create failed", __func__); 142570af302Sopenharmony_ci } 143570af302Sopenharmony_ci 144570af302Sopenharmony_ci result = thrd_sleep(&(struct timespec){.tv_sec = 1}, NULL); 145570af302Sopenharmony_ci if (result != 0) { 146570af302Sopenharmony_ci t_error("%s thrd_sleep failed", __func__); 147570af302Sopenharmony_ci } 148570af302Sopenharmony_ci 149570af302Sopenharmony_ci if (thrd_equal(thr1, thr2)) { 150570af302Sopenharmony_ci t_error("%s failed, thr1 and thr2 equal", __func__); 151570af302Sopenharmony_ci } 152570af302Sopenharmony_ci 153570af302Sopenharmony_ci if (thrd_equal(thr1, thrd_current())) { 154570af302Sopenharmony_ci t_error("%s failed, thr1 and current thread equal", __func__); 155570af302Sopenharmony_ci } 156570af302Sopenharmony_ci 157570af302Sopenharmony_ci if (thrd_equal(thr2, thrd_current())) { 158570af302Sopenharmony_ci t_error("%s failed, thr2 and current thread equal", __func__); 159570af302Sopenharmony_ci } 160570af302Sopenharmony_ci 161570af302Sopenharmony_ci result = thrd_join(thr1, NULL); 162570af302Sopenharmony_ci if (result != thrd_success) { 163570af302Sopenharmony_ci t_error("%s thrd_join failed", __func__); 164570af302Sopenharmony_ci } 165570af302Sopenharmony_ci 166570af302Sopenharmony_ci result = thrd_join(thr2, NULL); 167570af302Sopenharmony_ci if (result != thrd_success) { 168570af302Sopenharmony_ci t_error("%s thrd_join failed", __func__); 169570af302Sopenharmony_ci } 170570af302Sopenharmony_ci 171570af302Sopenharmony_ci if (count != 2) { 172570af302Sopenharmony_ci t_error("%s failed, count is %d", __func__, count); 173570af302Sopenharmony_ci } 174570af302Sopenharmony_ci count = 0; 175570af302Sopenharmony_ci} 176570af302Sopenharmony_ci 177570af302Sopenharmony_ciint main(int argc, char *argv[]) 178570af302Sopenharmony_ci{ 179570af302Sopenharmony_ci thrd_equal_0100(); 180570af302Sopenharmony_ci thrd_equal_0200(); 181570af302Sopenharmony_ci return t_status; 182570af302Sopenharmony_ci}