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 count++; 66570af302Sopenharmony_ci thrd_t id = thrd_current(); 67570af302Sopenharmony_ci if (!(thrd_equal(id, thr))) { 68570af302Sopenharmony_ci t_error("%s thrd_current failed", __func__); 69570af302Sopenharmony_ci } 70570af302Sopenharmony_ci 71570af302Sopenharmony_ci thrd_exit(thrd_success); 72570af302Sopenharmony_ci} 73570af302Sopenharmony_ci 74570af302Sopenharmony_ciint threadfuncB(void *arg) 75570af302Sopenharmony_ci{ 76570af302Sopenharmony_ci int result = TrylockWithTimeout(&g_mutex); 77570af302Sopenharmony_ci if (result == LOCK_SUCCESS) { 78570af302Sopenharmony_ci count++; 79570af302Sopenharmony_ci pthread_mutex_unlock(&g_mutex); 80570af302Sopenharmony_ci } else if (result == LOCK_TIMEOUT) { 81570af302Sopenharmony_ci t_error("Lock acquisition timed out.\n"); 82570af302Sopenharmony_ci } else { 83570af302Sopenharmony_ci t_error("Error pthread_mutex_trylock.\n"); 84570af302Sopenharmony_ci } 85570af302Sopenharmony_ci 86570af302Sopenharmony_ci thrd_exit(thrd_success); 87570af302Sopenharmony_ci} 88570af302Sopenharmony_ci 89570af302Sopenharmony_ci/** 90570af302Sopenharmony_ci * @tc.name : thrd_current_0100 91570af302Sopenharmony_ci * @tc.desc : Returns the identifier of the calling thread 92570af302Sopenharmony_ci * @tc.level : Level 0 93570af302Sopenharmony_ci */ 94570af302Sopenharmony_civoid thrd_current_0100(void) 95570af302Sopenharmony_ci{ 96570af302Sopenharmony_ci int result; 97570af302Sopenharmony_ci 98570af302Sopenharmony_ci result = thrd_create(&thr, threadfuncA, NULL); 99570af302Sopenharmony_ci if (result != thrd_success) { 100570af302Sopenharmony_ci t_error("%s thrd_create failed", __func__); 101570af302Sopenharmony_ci } 102570af302Sopenharmony_ci 103570af302Sopenharmony_ci result = thrd_sleep(&(struct timespec){.tv_sec = 1}, NULL); 104570af302Sopenharmony_ci if (result != 0) { 105570af302Sopenharmony_ci t_error("%s thrd_sleep failed", __func__); 106570af302Sopenharmony_ci } 107570af302Sopenharmony_ci 108570af302Sopenharmony_ci result = thrd_join(thr, NULL); 109570af302Sopenharmony_ci if (result != thrd_success) { 110570af302Sopenharmony_ci t_error("%s thrd_join failed", __func__); 111570af302Sopenharmony_ci } 112570af302Sopenharmony_ci 113570af302Sopenharmony_ci if (count != 1) { 114570af302Sopenharmony_ci t_error("%s failed, count is %d", __func__, count); 115570af302Sopenharmony_ci } 116570af302Sopenharmony_ci count = 0; 117570af302Sopenharmony_ci} 118570af302Sopenharmony_ci 119570af302Sopenharmony_ci/** 120570af302Sopenharmony_ci * @tc.name : thrd_current_0200 121570af302Sopenharmony_ci * @tc.desc : Create two threads to execute the same func 122570af302Sopenharmony_ci * @tc.level : Level 1 123570af302Sopenharmony_ci */ 124570af302Sopenharmony_civoid thrd_current_0200(void) 125570af302Sopenharmony_ci{ 126570af302Sopenharmony_ci thrd_t thr1, thr2; 127570af302Sopenharmony_ci int result; 128570af302Sopenharmony_ci 129570af302Sopenharmony_ci result = thrd_create(&thr1, threadfuncB, NULL); 130570af302Sopenharmony_ci if (result != thrd_success) { 131570af302Sopenharmony_ci t_error("%s thrd_create failed", __func__); 132570af302Sopenharmony_ci } 133570af302Sopenharmony_ci 134570af302Sopenharmony_ci result = thrd_create(&thr2, 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_sleep(&(struct timespec){.tv_sec = 1}, NULL); 140570af302Sopenharmony_ci if (result != 0) { 141570af302Sopenharmony_ci t_error("%s thrd_sleep failed", __func__); 142570af302Sopenharmony_ci } 143570af302Sopenharmony_ci 144570af302Sopenharmony_ci if (thrd_equal(thr1, thr2)) { 145570af302Sopenharmony_ci t_error("%s equal", __func__); 146570af302Sopenharmony_ci } 147570af302Sopenharmony_ci 148570af302Sopenharmony_ci if (thrd_equal(thr1, thrd_current())) { 149570af302Sopenharmony_ci t_error("%s equal", __func__); 150570af302Sopenharmony_ci } 151570af302Sopenharmony_ci 152570af302Sopenharmony_ci if (thrd_equal(thr2, thrd_current())) { 153570af302Sopenharmony_ci t_error("%s equal", __func__); 154570af302Sopenharmony_ci } 155570af302Sopenharmony_ci 156570af302Sopenharmony_ci result = thrd_join(thr1, NULL); 157570af302Sopenharmony_ci if (result != thrd_success) { 158570af302Sopenharmony_ci t_error("%s thrd_join failed", __func__); 159570af302Sopenharmony_ci } 160570af302Sopenharmony_ci 161570af302Sopenharmony_ci result = thrd_join(thr2, NULL); 162570af302Sopenharmony_ci if (result != thrd_success) { 163570af302Sopenharmony_ci t_error("%s thrd_join failed", __func__); 164570af302Sopenharmony_ci } 165570af302Sopenharmony_ci 166570af302Sopenharmony_ci if (count != 2) { 167570af302Sopenharmony_ci t_error("%s failed, count is %d", __func__, count); 168570af302Sopenharmony_ci } 169570af302Sopenharmony_ci count = 0; 170570af302Sopenharmony_ci} 171570af302Sopenharmony_ci 172570af302Sopenharmony_ciint main(int argc, char *argv[]) 173570af302Sopenharmony_ci{ 174570af302Sopenharmony_ci thrd_current_0100(); 175570af302Sopenharmony_ci thrd_current_0200(); 176570af302Sopenharmony_ci return t_status; 177570af302Sopenharmony_ci}