diff --git a/mutex/gjb_S0100504GN_1.c b/mutex/gjb_S0100504GN_1.c new file mode 100644 index 0000000000000000000000000000000000000000..a353bae1ecd7ceabc6acf9eddd63dacf5a8cc64c --- /dev/null +++ b/mutex/gjb_S0100504GN_1.c @@ -0,0 +1,83 @@ +/********************************************************************************************************* +** +** GJB 标准测试集 +** +** Copyright All Rights Reserved +** +**--------------文件信息-------------------------------------------------------------------------------- +** +** 文 件 名: gjb_S0100504GN_1.c +** +** 文件创建日期: 2021 年 1 月 12 日 +** +** 描 述: 永久等待方式获取互斥量测试。编制驱动代码. 创建恰当的二互斥量, 以永久等待方式申请互斥量; +** 当互斥量未被锁定时, 当前任务/进程锁定互斥量,并成功返回; +** 如果互斥量不可用, 那么任务/进程不返回,直到成功获得互斥量. +*********************************************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include + + +int main(int argc, char **argv) +{ + int rc = 0; + pthread_mutexattr_t mta; + pthread_mutex_t mutex1; + + /* Initialize mutex attribute objects with default values */ + if ((rc = pthread_mutexattr_init(&mta)) == 0) { + printf("Initialize mutex attribute objects with default values successful.\n"); + } else { + printf("Initialize mutex attribute objects with default values failed!, errno=%d\n",errno); + goto __errno_handle; + } + + /* Initialize the mutex with the default mutex attribute object*/ + if ((rc = pthread_mutex_init(&mutex1, &mta)) == 0) { + printf("Initialize the mutex with the default mutex attribute object successful. TEST PASS.\n"); + } else { + printf("Initialize the mutex with the default mutex attribute object failed! errno=%d.TEST FAILED\n",errno); + pthread_mutexattr_destroy(&mta); + goto __errno_handle; + } + + //lock (获取互斥量, 如果获取不能获取将永久等待) + if ((rc = pthread_mutex_lock(&mutex1)) == 0) { + printf("lock mutex successful. TEST PASS.\n"); + } else { + printf("lock mutex failed! errno=%d.TEST FAILED.\n",errno); + pthread_mutex_destroy(&mutex1); + pthread_mutexattr_destroy(&mta); + goto __errno_handle; + } + + //unlock + if ((rc = pthread_mutex_unlock(&mutex1)) != 0) { + printf("unlock mutex failed. TEST failed.\n"); + goto __errno_handle; + } + + /* Destroy Mutex mutex1*/ + if ((rc = pthread_mutex_destroy(&mutex1)) == 0) { + printf("Destroy Mutex mutex1 successful. TEST PASS.\n"); + } else { + printf("Destroy Mutex mutex1 failed! errno=%d.TEST FAILED\n",errno); + pthread_mutexattr_destroy(&mta); + goto __errno_handle; + } + + pthread_mutexattr_destroy(&mta); + + printf("..................................................[PASS]\n"); + return 0; + +__errno_handle: + printf("..................................................[FAILED]\n"); + return -1; +} diff --git a/mutex/gjb_S0100504GN_3.c b/mutex/gjb_S0100504GN_3.c new file mode 100644 index 0000000000000000000000000000000000000000..3c48ac0071ba32a824d0886dfc12e12f803c8385 --- /dev/null +++ b/mutex/gjb_S0100504GN_3.c @@ -0,0 +1,94 @@ +/********************************************************************************************************* +** +** GJB 标准测试集 +** +** Copyright All Rights Reserved +** +**--------------文件信息-------------------------------------------------------------------------------- +** +** 文 件 名: gjb_S0100504GN_2.c +** +** 文件创建日期: 2021 年 1 月 12 日 +** +** 描 述: 永久等待方式获取互斥量测试。编制驱动代码. 创建恰当的二互斥量, 以永久等待方式申请互斥量; +** 当互斥量未被锁定时, 当前任务/进程锁定互斥量,并成功返回; +** 如果互斥量不可用, 那么任务/进程不返回,直到成功获得互斥量. +*********************************************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + int rc; + pthread_mutex_t mutex; + pthread_mutexattr_t mta; + + pthread_mutexattr_init(&mta); + + /* Set the type attribute of the mutex to PTHREAD_MUTEX_ERRORCHECK */ + if ((rc = pthread_mutexattr_settype(&mta,PTHREAD_MUTEX_ERRORCHECK)) != 0) { + printf("Set the type attribute of the mutex to PTHREAD_MUTEX_ERRORCHECK failed!, errno=%d\n", errno); + goto __errno_handle; + + } else { + printf("Set the type attribute of the mutex to PTHREAD_MUTEX_ERRORCHECK successful.\n"); + } + + if((rc = pthread_mutex_init(&mutex,&mta)) != 0) { + printf("Initialization mutex failed!, errno=%d\n",errno); + goto __errno_handle; + + } else { + printf("Initialization mutex successful.\n"); + } + + /* Locking unlocked mutexes in a blocking manner */ + rc = pthread_mutex_lock(&mutex); + if (rc != 0) { + printf("Locking unlocked mutexes in a blocking manner failed!, errno=%d\n",errno); + pthread_mutex_destroy(&mutex); + goto __errno_handle; + + } else { + printf("Locking unlocked mutexes in a blocking manner successful.\n"); + } + + /* Locking locked mutexes in a blocking manner */ + rc = pthread_mutex_lock(&mutex); + if (rc == 0) { + printf("Locking locked mutexes in a blocking manner successful.TEST FAILED!\n"); + pthread_mutex_destroy(&mutex); + goto __errno_handle; + + } else { + if (EDEADLK == rc) + printf("Locking locked mutexes in a blocking manner failed!, errno=%d=EDEADLK. TEST PASS!\n",rc); + else + printf("Locking locked mutexes in a blocking manner failed!, errno=%d!=EDEADLK. TEST FAILED!\n",errno); + } + + if (pthread_mutex_unlock(&mutex) != 0) { + printf("Unlocking Mutex Failure, errno=%d\n",errno); + goto __errno_handle; + } + + /* Destroy Mutex */ + rc = pthread_mutex_destroy(&mutex); + if (rc != 0) { + printf("Destroy Mutex failed!, errno=%d\n",errno); + goto __errno_handle; + } + + printf("..................................................[PASS]\n"); + return 0; + +__errno_handle: + printf("..................................................[FAILED]\n"); + return -1; +} diff --git a/mutex/gjb_S0100504GN_4.c b/mutex/gjb_S0100504GN_4.c new file mode 100644 index 0000000000000000000000000000000000000000..07cb03a3fadab86e6c5d00090569a6e10680a2d4 --- /dev/null +++ b/mutex/gjb_S0100504GN_4.c @@ -0,0 +1,135 @@ +/********************************************************************************************************* +** +** GJB 标准测试集 +** +** Copyright All Rights Reserved +** +**--------------文件信息-------------------------------------------------------------------------------- +** +** 文 件 名: gjb_S0100504GN_2.c +** +** 文件创建日期: 2021 年 1 月 12 日 +** +** 描 述: 永久等待方式获取互斥量测试。编制驱动代码. 创建恰当的二互斥量, 以永久等待方式申请互斥量; +** 当互斥量未被锁定时, 当前任务/进程锁定互斥量,并成功返回; +** 如果互斥量不可用, 那么任务/进程不返回,直到成功获得互斥量. +*********************************************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define THREAD_NUM 5 +#define LOOPS 4 +#define SYSTEM_TICKS_USEC 1000 + +static int err_count_5044; +static pthread_mutex_t mutex_04GN1 = PTHREAD_MUTEX_INITIALIZER; +static int value_04GN1 = 0; /* value_04GN1 protected by mutex_04GN1 */ + +void *pthread_mutex_lock_f1(void *parm) +{ + int i; + int tmp = 0; + int rc = 0; + pthread_t self = pthread_self(); + + /* + * Loopd M times to acquire the mutex_04GN1, increase the value_04GN1, + * and then release the mutex_04GN1. + */ + + for (i = 0; i < LOOPS; ++i) { + rc = pthread_mutex_lock(&mutex_04GN1); + if (rc != 0) { + printf("Error on pthread_mutex_lock(), rc=%d\n", rc); + err_count_5044++; + } + + tmp = value_04GN1; + tmp = tmp + 1; + + printf("Thread(0x%p) holds the mutex_04GN1\n",(void*)self); + pthread_delay(10); /* delay the increasement operation */ + + value_04GN1 = tmp; + + rc = pthread_mutex_unlock(&mutex_04GN1); + if (rc != 0) { + printf("Error on pthread_mutex_unlock(), rc=%d\n", rc); + err_count_5044++; + } + + sleep(1); + } + + pthread_exit(0); + return (void*)(0); +} + +int main(int argc, char **argv) +{ + int i; + pthread_attr_t pta; + pthread_t threads[THREAD_NUM]; + + pthread_attr_init(&pta); + pthread_attr_setdetachstate(&pta, PTHREAD_CREATE_JOINABLE); + + /* Create threads */ + printf("Creating %d threads\n", THREAD_NUM); + + for (i = 0; i < THREAD_NUM; i++) { + pthread_create(&threads[i], &pta, pthread_mutex_lock_f1, NULL); + } + + /* Wait to join all threads */ + for (i = 0; i < THREAD_NUM; ++i) { + pthread_join(threads[i], NULL); + } + + pthread_attr_destroy(&pta); + pthread_mutex_destroy(&mutex_04GN1); + + /* Check if the final value_04GN1 is as expected */ + if (value_04GN1 != (THREAD_NUM) * LOOPS) { + printf("Using %d threads and each loops %d times\n", THREAD_NUM, LOOPS); + printf("Final value_04GN1 must be %d instead of %d.TEST FAILED!\n", (THREAD_NUM)*LOOPS, value_04GN1); + goto __errno_handle; + } + + if (err_count_5044) { + goto __errno_handle; + } + + printf("..................................................[PASS]\n"); + return 0; + +__errno_handle: + printf("..................................................[FAILED]\n"); + return -1; +} + + +unsigned long long g_pthread_delay_tick; +int is_set_sys_rate; +unsigned int g_sys_uleep_tick; +int pthread_delay(int ticks) +{ + g_pthread_delay_tick = ticks; + sched_yield(); + if(is_set_sys_rate) + { + return usleep(g_sys_uleep_tick * ticks); + } + else + { + return usleep(SYSTEM_TICKS_USEC * ticks); + } +} diff --git a/mutex/gjb_S0100505GN_1.c b/mutex/gjb_S0100505GN_1.c new file mode 100644 index 0000000000000000000000000000000000000000..0edbbc61d36ee39c249c974cab40dd50c2f5a3de --- /dev/null +++ b/mutex/gjb_S0100505GN_1.c @@ -0,0 +1,83 @@ +/********************************************************************************************************* +** +** GJB 标准测试集 +** +** Copyright All Rights Reserved +** +**--------------文件信息-------------------------------------------------------------------------------- +** +** 文 件 名: gjb_S0100505GN_1.c +** +** 文件创建日期: 2021 年 1 月 12 日 +** +** 描 述: 限时等待方式获取互斥量测试 +*********************************************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + int rc; + + pthread_mutex_t mutex; + pthread_mutexattr_t mta; + + struct timespec timeout; + + //Initialization waiting absolute time + + clock_gettime(CLOCK_REALTIME, &timeout); + + timeout.tv_sec += 3; + timeout.tv_nsec += 0; + + pthread_mutexattr_init(&mta); + + /* Set the type attribute of the mutex to PTHREAD_MUTEX_ERRORCHECK */ + if ((rc = pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_ERRORCHECK)) != 0) { + printf("Set the type attribute of the mutex to PTHREAD_MUTEX_ERRORCHECK failed!, errno=%d\n",errno); + goto __errno_handle; + } + + if ((rc = pthread_mutex_init(&mutex, &mta)) != 0) { + printf("Initialization mutex failed!, errno=%d\n",errno); + goto __errno_handle; + } + + /* Locking unlocked mutexes 限时等待方式获取互斥量 */ + rc = pthread_mutex_timedlock(&mutex,&timeout); + if (rc != 0) { + printf("Locking unlocked mutexes in pthread_mutex_timedlock manner failed!, errno=%d. TEST FAILED.\n",errno); + pthread_mutex_destroy(&mutex); + goto __errno_handle; + + } else { + printf("Locking unlocked mutexes in pthread_mutex_timedlock manner successful.TEST PASS.\n"); + } + + if (pthread_mutex_unlock(&mutex) != 0) { + printf("Unlocking Mutex Failure, errno=%d\n",errno); + goto __errno_handle; + } + + /* Destroy Mutex */ + rc = pthread_mutex_destroy(&mutex); + if (rc != 0) { + printf("Destroy Mutex failed!, errno=%d\n",errno); + goto __errno_handle; + } + + printf("..................................................[PASS]\n"); + return 0; + +__errno_handle: + printf("..................................................[FAILED]\n"); + return -1; +} diff --git a/mutex/gjb_S0100505GN_3.c b/mutex/gjb_S0100505GN_3.c new file mode 100644 index 0000000000000000000000000000000000000000..4126e32e7027c8322314dd5553a7ff3ad24df0ac --- /dev/null +++ b/mutex/gjb_S0100505GN_3.c @@ -0,0 +1,99 @@ +/********************************************************************************************************* +** +** GJB 标准测试集 +** +** Copyright All Rights Reserved +** +**--------------文件信息-------------------------------------------------------------------------------- +** +** 文 件 名: gjb_S0100505GN_2.c +** +** 文件创建日期: 2021 年 1 月 12 日 +** +** 描 述: 限时等待方式获取互斥量测试 +*********************************************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + int rc; + pthread_mutex_t mutex; + pthread_mutexattr_t mta; + //Initialization waiting absolute time + struct timespec timeout; + clock_gettime(CLOCK_REALTIME, &timeout); + timeout.tv_sec += 3; + timeout.tv_nsec += 0; + + pthread_mutexattr_init(&mta); + + /* Set the type attribute of the mutex to PTHREAD_MUTEX_ERRORCHECK */ + if ((rc = pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_ERRORCHECK)) != 0) { + printf("Set the type attribute of the mutex to PTHREAD_MUTEX_ERRORCHECK failed!, errno=%d\n", errno); + goto __errno_handle; + + } else { + printf("Set the type attribute of the mutex to PTHREAD_MUTEX_ERRORCHECK successful.\n"); + } + + if ((rc = pthread_mutex_init(&mutex,&mta)) != 0) { + printf("Initialization mutex failed!, errno=%d\n", errno); + goto __errno_handle; + + } else { + printf("Initialization mutex successful.\n"); + } + + /* Locking unlocked mutexes */ + rc = pthread_mutex_timedlock(&mutex,&timeout); + if (rc != 0) { + printf("Locking unlocked mutexes in pthread_mutex_timedlock manner failed!, errno=%d. TEST FAILED.\n", errno); + pthread_mutex_destroy(&mutex); + goto __errno_handle; + + } else { + printf("Locking unlocked mutexes in pthread_mutex_timedlock manner successful.TEST PASS.\n"); + } + + /* Locking locked mutexes */ + rc = pthread_mutex_timedlock(&mutex,&timeout); + if (rc == 0) { + printf("Locking locked mutexes in pthread_mutex_timedlock manner successful.TEST FAILED!\n"); + pthread_mutex_destroy(&mutex); + goto __errno_handle; + + } else { + if (EDEADLK==rc) + printf("Locking locked mutexes in pthread_mutex_timedlock manner failed!, errno=%d=EDEADLK. TEST PASS!\n",errno); + else { + printf("Locking locked mutexes in pthread_mutex_timedlock manner failed!, errno=%d!=EDEADLK. TEST FAILED!\n",errno); + goto __errno_handle; + } + } + + if (pthread_mutex_unlock(&mutex) != 0) { + printf("Unlocking Mutex Failure, errno=%d\n",errno); + goto __errno_handle; + } + + /* Destroy Mutex */ + rc = pthread_mutex_destroy(&mutex); + if (rc != 0) { + printf("Destroy Mutex failed!, errno=%d\n",errno); + goto __errno_handle; + } + printf("..................................................[PASS]\n"); + return 0; + +__errno_handle: + printf("..................................................[FAILED]\n"); + return -1; +} diff --git a/mutex/gjb_S0100505GN_4.c b/mutex/gjb_S0100505GN_4.c new file mode 100644 index 0000000000000000000000000000000000000000..86a432cfe4431e46c73c013e0706fe1afde64c01 --- /dev/null +++ b/mutex/gjb_S0100505GN_4.c @@ -0,0 +1,124 @@ +/********************************************************************************************************* +** +** GJB 标准测试集 +** +** Copyright All Rights Reserved +** +**--------------文件信息-------------------------------------------------------------------------------- +** +** 文 件 名: gjb_S0100505GN_4.c +** +** 文件创建日期: 2021 年 1 月 12 日 +** +** 描 述: 限时等待方式获取互斥量测试 +*********************************************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TIMEOUT 3 /* 3 seconds of timeout time for pthread_mutex_timedlock(). */ +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; /* The mutex */ +struct timespec currsec1, currsec2; /* Variables for saving time before and after locking the mutex using pthread_mutex_timedlock(). */ +static int err_count_5054 = 0; + +void *f1(void *parm) +{ + struct timespec timeout; + int rc; + + /* Get the current time before the mutex locked. */ + clock_gettime(CLOCK_REALTIME, &currsec1); + + /* Absolute time, not relative. */ + timeout.tv_sec = currsec1.tv_sec + TIMEOUT; + timeout.tv_nsec = currsec1.tv_nsec ; + + printf("Timed mutex lock will block for %d seconds starting from: %ld.%06ld\n", + TIMEOUT, (long)currsec1.tv_sec, (long)currsec1.tv_nsec); + + /* + * 这里再次获取信号量将获取失败并等待直到超时返回 ETIMEDOUT 错误 + */ + if ((rc = pthread_mutex_timedlock(&mutex, &timeout) ) != ETIMEDOUT) { + printf("Error in pthread_mutex_timedlock(), errno=%d\n",errno); + err_count_5054++; + return (void*)-1; + } + + /* Get time after the mutex timed out in locking. */ + clock_gettime(CLOCK_REALTIME, &currsec2); + + pthread_exit(0); + return (void*)(0); +} + +int main(int argc, char **argv) +{ + pthread_t new_th; + struct timespec time_diff; + + /* Lock the mutex. 首先获取互斥量量 */ + if (pthread_mutex_lock(&mutex) != 0) { + printf("Error in pthread_mutex_lock(). errno=%d\n",errno); + goto __errno_handle; + } + + /* + * Create a thread that will call pthread_mutex_timedlock + */ + if (pthread_create(&new_th, NULL, f1, NULL) != 0) { + printf("Error in pthread_create(), errno=%d\n",errno); + goto __errno_handle; + } + + /* + * Wait for thread to end. + */ + if (pthread_join(new_th, NULL) != 0) { + printf("Error in pthread_join(), errno=%d\n",errno); + goto __errno_handle; + } + + /* Cleaning up the mutexes. */ + if (pthread_mutex_unlock(&mutex) != 0) { + printf("Error in pthread_mutex_unlock(), errno=%d\n",errno); + goto __errno_handle; + } + + if (pthread_mutex_destroy(&mutex) != 0) { + printf("Error in pthread_mutex_destroy(), errno=%d\n",errno); + goto __errno_handle; + } + + /* Compare time before the mutex locked and after the mutex lock timed out. */ + time_diff.tv_sec = currsec2.tv_sec - currsec1.tv_sec; + time_diff.tv_nsec = currsec2.tv_nsec - currsec1.tv_nsec; + + if (time_diff.tv_nsec < 0) { + --time_diff.tv_sec; + time_diff.tv_nsec += 1000000000; + } + + if (time_diff.tv_sec < TIMEOUT) { + printf("Test FAILED: Timed lock did not wait long enough. (%d secs.). TEST FAILED!\n", TIMEOUT); + printf("time before mutex locked: %ld.%06ld, time after mutex timed out: %ld.%06ld.\n", (long)currsec1.tv_sec, (long)currsec1.tv_nsec, (long)currsec2.tv_sec, (long)currsec2.tv_nsec); + goto __errno_handle; + } + + if (err_count_5054) { + goto __errno_handle; + } + + printf("..................................................[PASS]\n"); + return 0; + +__errno_handle: + printf("..................................................[FAILED]\n"); + return -1; +}