diff --git a/conformance/definitions/pthread_h/2-2.c b/conformance/definitions/pthread_h/2-2.c deleted file mode 100644 index 65300d7..0000000 --- a/conformance/definitions/pthread_h/2-2.c +++ /dev/null @@ -1,63 +0,0 @@ - - /* - * Copyright (c) 2002, Intel Corporation. All rights reserved. - * Created by: rolla.n.selbak REMOVE-THIS AT intel DOT com - * This file is licensed under the GPL license. For the full content - * of this license, see the COPYING file at the top level of this - * source tree. - - Test the following symbols are defined by pthread.h - */ - -#include - -/* BAR */ -#ifndef PTHREAD_BARRIER_SERIAL_THREAD -#error PTHREAD_BARRIER_SERIAL_THREAD not defined -#endif - -/* XSI */ -#ifndef PTHREAD_MUTEX_DEFAULT -#error PTHREAD_MUTEX_DEFAULT not defined -#endif - -/* XSI */ -#ifndef PTHREAD_MUTEX_ERRORCHECK -#error PTHREAD_MUTEX_ERRORCHECK not defined -#endif - -/* XSI */ -#ifndef PTHREAD_MUTEX_NORMAL -#error PTHREAD_MUTEX_NORMAL not defined -#endif - -/* XSI */ -#ifndef PTHREAD_MUTEX_RECURSIVE -#error PTHREAD_MUTEX_RECURSIVE not defined -#endif - -/* TPP|TPI */ -#ifndef PTHREAD_PRIO_INHERIT -#error PTHREAD_PRIO_INHERIT not defined -#endif - -/* TPP|TPI */ -#ifndef PTHREAD_PRIO_NONE -#error PTHREAD_PRIO_NONE not defined -#endif - -/* TPP|TPI */ -#ifndef PTHREAD_PRIO_PROTECT -#error PTHREAD_PRIO_PROTECT not defined -#endif - -/* TPS */ -#ifndef PTHREAD_SCOPE_PROCESS -#error PTHREAD_SCOPE_PROCESS not defined -#endif - -/* TPS */ -#ifndef PTHREAD_SCOPE_SYSTEM -#error PTHREAD_SCOPE_SYSTEM not defined -#endif - diff --git a/conformance/definitions/time_h/27-1.c b/conformance/definitions/time_h/27-1.c index 7c95a87..65e13dd 100644 --- a/conformance/definitions/time_h/27-1.c +++ b/conformance/definitions/time_h/27-1.c @@ -10,7 +10,7 @@ char *strptime(const char *, const char *, struct tm *); is declared. */ - +#define _XOPEN_SOURCE #include typedef char *(*strptime_test)(const char *, const char *, struct tm *); diff --git a/conformance/definitions/time_h/7-1.c b/conformance/definitions/time_h/7-1.c index a9404f7..5e2a2dc 100644 --- a/conformance/definitions/time_h/7-1.c +++ b/conformance/definitions/time_h/7-1.c @@ -9,5 +9,6 @@ */ #include +#include clock_t dummy; diff --git a/conformance/interfaces/aio_cancel/3-1.c b/conformance/interfaces/aio_cancel/3-1.c index 3f7f4e1..c0325c5 100644 --- a/conformance/interfaces/aio_cancel/3-1.c +++ b/conformance/interfaces/aio_cancel/3-1.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "posixtest.h" diff --git a/conformance/interfaces/aio_read/1-1.c b/conformance/interfaces/aio_read/1-1.c index 79e71af..3695c97 100644 --- a/conformance/interfaces/aio_read/1-1.c +++ b/conformance/interfaces/aio_read/1-1.c @@ -26,6 +26,8 @@ #include #include +#include +#include #include "posixtest.h" #define TNAME "aio_read/1-1.c" diff --git a/conformance/interfaces/aio_read/15-1.c b/conformance/interfaces/aio_read/15-1.c index 5c02788..995ee35 100644 --- a/conformance/interfaces/aio_read/15-1.c +++ b/conformance/interfaces/aio_read/15-1.c @@ -24,6 +24,10 @@ #include #include +#include +#include +#include +#include #include "posixtest.h" int main() diff --git a/conformance/interfaces/aio_read/9-1.c b/conformance/interfaces/aio_read/9-1.c index 201dddb..43de6e0 100644 --- a/conformance/interfaces/aio_read/9-1.c +++ b/conformance/interfaces/aio_read/9-1.c @@ -31,6 +31,8 @@ #include #include +#include +#include #include "posixtest.h" #define TNAME "aio_read/9-1.c" diff --git a/conformance/interfaces/aio_return/2-1.c b/conformance/interfaces/aio_return/2-1.c index 5b7536e..e70e2c7 100644 --- a/conformance/interfaces/aio_return/2-1.c +++ b/conformance/interfaces/aio_return/2-1.c @@ -28,6 +28,8 @@ #include #include +#include +#include #include "posixtest.h" #define TNAME "aio_return/2-1.c" diff --git a/conformance/interfaces/aio_return/4-1.c b/conformance/interfaces/aio_return/4-1.c index 365521e..4afe150 100644 --- a/conformance/interfaces/aio_return/4-1.c +++ b/conformance/interfaces/aio_return/4-1.c @@ -30,6 +30,8 @@ #include #include +#include +#include #include "posixtest.h" #define TNAME "aio_return/4-1.c" diff --git a/conformance/interfaces/aio_suspend/1-1.c b/conformance/interfaces/aio_suspend/1-1.c index 4ce3774..cf486bd 100644 --- a/conformance/interfaces/aio_suspend/1-1.c +++ b/conformance/interfaces/aio_suspend/1-1.c @@ -33,6 +33,8 @@ #include #include +#include +#include #include "posixtest.h" #define TNAME "aio_suspend/1-1.c" diff --git a/conformance/interfaces/aio_suspend/4-1.c b/conformance/interfaces/aio_suspend/4-1.c index 5681e30..c236f4c 100644 --- a/conformance/interfaces/aio_suspend/4-1.c +++ b/conformance/interfaces/aio_suspend/4-1.c @@ -30,6 +30,8 @@ #include #include +#include +#include #include "posixtest.h" #define TNAME "aio_suspend/4-1.c" diff --git a/conformance/interfaces/aio_suspend/6-1.c b/conformance/interfaces/aio_suspend/6-1.c index 1c6b8b1..09d01d7 100644 --- a/conformance/interfaces/aio_suspend/6-1.c +++ b/conformance/interfaces/aio_suspend/6-1.c @@ -29,6 +29,8 @@ #include #include +#include +#include #include "posixtest.h" #define TNAME "aio_suspend/6-1.c" diff --git a/conformance/interfaces/aio_suspend/7-1.c b/conformance/interfaces/aio_suspend/7-1.c index 1afaa0a..cc953c4 100644 --- a/conformance/interfaces/aio_suspend/7-1.c +++ b/conformance/interfaces/aio_suspend/7-1.c @@ -30,6 +30,8 @@ #include #include +#include +#include #include "posixtest.h" #define TNAME "aio_suspend/7-1.c" diff --git a/conformance/interfaces/aio_suspend/8-1.c b/conformance/interfaces/aio_suspend/8-1.c index 7ce3c8b..a64e119 100644 --- a/conformance/interfaces/aio_suspend/8-1.c +++ b/conformance/interfaces/aio_suspend/8-1.c @@ -34,6 +34,8 @@ #include #include +#include +#include #include "posixtest.h" #define TNAME "aio_suspend/8-1.c" diff --git a/conformance/interfaces/aio_suspend/9-1.c b/conformance/interfaces/aio_suspend/9-1.c index 8912a89..9267314 100644 --- a/conformance/interfaces/aio_suspend/9-1.c +++ b/conformance/interfaces/aio_suspend/9-1.c @@ -30,6 +30,8 @@ #include #include +#include +#include #include "posixtest.h" #define TNAME "aio_suspend/9-1.c" diff --git a/conformance/interfaces/aio_write/7-1.c b/conformance/interfaces/aio_write/7-1.c index 8f13f30..2d6d401 100644 --- a/conformance/interfaces/aio_write/7-1.c +++ b/conformance/interfaces/aio_write/7-1.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "posixtest.h" diff --git a/conformance/interfaces/lio_listio/1-1.c b/conformance/interfaces/lio_listio/1-1.c index c86e318..4402f7e 100644 --- a/conformance/interfaces/lio_listio/1-1.c +++ b/conformance/interfaces/lio_listio/1-1.c @@ -29,6 +29,8 @@ #include #include +#include +#include #include "posixtest.h" #define TNAME "lio_listio/1-1.c" diff --git a/conformance/interfaces/lio_listio/10-1.c b/conformance/interfaces/lio_listio/10-1.c index fbe82ec..a0a6235 100644 --- a/conformance/interfaces/lio_listio/10-1.c +++ b/conformance/interfaces/lio_listio/10-1.c @@ -28,6 +28,8 @@ #include #include +#include +#include #include "posixtest.h" #define TNAME "lio_listio/10-1.c" diff --git a/conformance/interfaces/lio_listio/11-1.c b/conformance/interfaces/lio_listio/11-1.c index 5938162..218503f 100644 --- a/conformance/interfaces/lio_listio/11-1.c +++ b/conformance/interfaces/lio_listio/11-1.c @@ -28,6 +28,8 @@ #include #include +#include +#include #include "posixtest.h" #define TNAME "lio_listio/11-1.c" diff --git a/conformance/interfaces/lio_listio/12-1.c b/conformance/interfaces/lio_listio/12-1.c index 46907a6..58defa9 100644 --- a/conformance/interfaces/lio_listio/12-1.c +++ b/conformance/interfaces/lio_listio/12-1.c @@ -28,6 +28,8 @@ #include #include +#include +#include #include "posixtest.h" #define TNAME "lio_listio/12-1.c" diff --git a/conformance/interfaces/lio_listio/13-1.c b/conformance/interfaces/lio_listio/13-1.c index b500947..e8a79e7 100644 --- a/conformance/interfaces/lio_listio/13-1.c +++ b/conformance/interfaces/lio_listio/13-1.c @@ -28,6 +28,8 @@ #include #include +#include +#include #include "posixtest.h" #define TNAME "lio_listio/13-1.c" diff --git a/conformance/interfaces/lio_listio/14-1.c b/conformance/interfaces/lio_listio/14-1.c index 8e66bd4..31c42f7 100644 --- a/conformance/interfaces/lio_listio/14-1.c +++ b/conformance/interfaces/lio_listio/14-1.c @@ -28,6 +28,8 @@ #include #include +#include +#include #include "posixtest.h" #define TNAME "lio_listio/14-1.c" diff --git a/conformance/interfaces/lio_listio/15-1.c b/conformance/interfaces/lio_listio/15-1.c index 6ae2b0d..cceb8c1 100644 --- a/conformance/interfaces/lio_listio/15-1.c +++ b/conformance/interfaces/lio_listio/15-1.c @@ -28,6 +28,8 @@ #include #include +#include +#include #include "posixtest.h" #define TNAME "lio_listio/15-1.c" diff --git a/conformance/interfaces/lio_listio/18-1.c b/conformance/interfaces/lio_listio/18-1.c index b998000..38f2463 100644 --- a/conformance/interfaces/lio_listio/18-1.c +++ b/conformance/interfaces/lio_listio/18-1.c @@ -29,6 +29,8 @@ #include #include +#include +#include #include "posixtest.h" #define TNAME "lio_listio/18-1.c" diff --git a/conformance/interfaces/lio_listio/2-1.c b/conformance/interfaces/lio_listio/2-1.c index 7fd1a03..d172303 100644 --- a/conformance/interfaces/lio_listio/2-1.c +++ b/conformance/interfaces/lio_listio/2-1.c @@ -27,6 +27,8 @@ #include #include +#include +#include #include "posixtest.h" #define TNAME "lio_listio/2-1.c" diff --git a/conformance/interfaces/lio_listio/3-1.c b/conformance/interfaces/lio_listio/3-1.c index 8445364..e5a6b47 100644 --- a/conformance/interfaces/lio_listio/3-1.c +++ b/conformance/interfaces/lio_listio/3-1.c @@ -28,6 +28,8 @@ #include #include +#include +#include #include "posixtest.h" #define TNAME "lio_listio/3-1.c" diff --git a/conformance/interfaces/lio_listio/4-1.c b/conformance/interfaces/lio_listio/4-1.c index e808e8c..adcc4ca 100644 --- a/conformance/interfaces/lio_listio/4-1.c +++ b/conformance/interfaces/lio_listio/4-1.c @@ -28,6 +28,8 @@ #include #include +#include +#include #include "posixtest.h" #define TNAME "lio_listio/4-1.c" diff --git a/conformance/interfaces/lio_listio/7-1.c b/conformance/interfaces/lio_listio/7-1.c index a512f06..4cefed0 100644 --- a/conformance/interfaces/lio_listio/7-1.c +++ b/conformance/interfaces/lio_listio/7-1.c @@ -31,6 +31,8 @@ #include #include +#include +#include #include "posixtest.h" #define TNAME "lio_listio/7-1.c" diff --git a/conformance/interfaces/mq_notify/2-1.c b/conformance/interfaces/mq_notify/2-1.c index de86758..835dadf 100644 --- a/conformance/interfaces/mq_notify/2-1.c +++ b/conformance/interfaces/mq_notify/2-1.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include "posixtest.h" #define TEST "2-1" diff --git a/conformance/interfaces/mq_notify/3-1.c b/conformance/interfaces/mq_notify/3-1.c index dbe813a..0ed02fe 100644 --- a/conformance/interfaces/mq_notify/3-1.c +++ b/conformance/interfaces/mq_notify/3-1.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include "posixtest.h" #define TEST "3-1" diff --git a/conformance/interfaces/mq_notify/5-1.c b/conformance/interfaces/mq_notify/5-1.c index f35046f..469ed86 100644 --- a/conformance/interfaces/mq_notify/5-1.c +++ b/conformance/interfaces/mq_notify/5-1.c @@ -33,6 +33,8 @@ #include #include #include +#include +#include #include "posixtest.h" #define TEST "5-1" diff --git a/conformance/interfaces/mq_notify/9-1.c b/conformance/interfaces/mq_notify/9-1.c index ed72727..d2b15dc 100644 --- a/conformance/interfaces/mq_notify/9-1.c +++ b/conformance/interfaces/mq_notify/9-1.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include "posixtest.h" #define TEST "9-1" diff --git a/conformance/interfaces/mq_open/16-1.c b/conformance/interfaces/mq_open/16-1.c index 14d901f..e0abcc4 100644 --- a/conformance/interfaces/mq_open/16-1.c +++ b/conformance/interfaces/mq_open/16-1.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "posixtest.h" #define NAMESIZE 50 diff --git a/conformance/interfaces/mq_open/2-1.c b/conformance/interfaces/mq_open/2-1.c index 586c1a7..3899d30 100644 --- a/conformance/interfaces/mq_open/2-1.c +++ b/conformance/interfaces/mq_open/2-1.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "posixtest.h" #define NAMESIZE 50 diff --git a/conformance/interfaces/mq_open/7-2.c b/conformance/interfaces/mq_open/7-2.c index e81effa..d6e380b 100644 --- a/conformance/interfaces/mq_open/7-2.c +++ b/conformance/interfaces/mq_open/7-2.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "posixtest.h" #define NAMESIZE 50 diff --git a/conformance/interfaces/mq_open/8-2.c b/conformance/interfaces/mq_open/8-2.c index d370863..4c2fdbd 100644 --- a/conformance/interfaces/mq_open/8-2.c +++ b/conformance/interfaces/mq_open/8-2.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "posixtest.h" #define NAMESIZE 50 diff --git a/conformance/interfaces/mq_open/9-2.c b/conformance/interfaces/mq_open/9-2.c index 3cdf081..1d1c157 100644 --- a/conformance/interfaces/mq_open/9-2.c +++ b/conformance/interfaces/mq_open/9-2.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "posixtest.h" #define NAMESIZE 50 diff --git a/conformance/interfaces/mq_receive/13-1.c b/conformance/interfaces/mq_receive/13-1.c index 28c73f0..3007b70 100644 --- a/conformance/interfaces/mq_receive/13-1.c +++ b/conformance/interfaces/mq_receive/13-1.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "posixtest.h" #define TEST "13-1" diff --git a/conformance/interfaces/mq_timedreceive/18-1.c b/conformance/interfaces/mq_timedreceive/18-1.c index ea904e3..24eac45 100644 --- a/conformance/interfaces/mq_timedreceive/18-1.c +++ b/conformance/interfaces/mq_timedreceive/18-1.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "posixtest.h" #define TEST "18-1" diff --git a/conformance/interfaces/mq_timedreceive/18-2.c b/conformance/interfaces/mq_timedreceive/18-2.c old mode 100644 new mode 100755 index 275e15b..0c58c58 --- a/conformance/interfaces/mq_timedreceive/18-2.c +++ b/conformance/interfaces/mq_timedreceive/18-2.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "posixtest.h" diff --git a/conformance/interfaces/mq_timedreceive/5-2.c b/conformance/interfaces/mq_timedreceive/5-2.c index 5afe2a3..64ddc4f 100644 --- a/conformance/interfaces/mq_timedreceive/5-2.c +++ b/conformance/interfaces/mq_timedreceive/5-2.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "posixtest.h" #define TEST "5-2" diff --git a/conformance/interfaces/mq_timedreceive/5-3.c b/conformance/interfaces/mq_timedreceive/5-3.c index bbdec0b..f767f05 100644 --- a/conformance/interfaces/mq_timedreceive/5-3.c +++ b/conformance/interfaces/mq_timedreceive/5-3.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "posixtest.h" #define TEST "5-3" diff --git a/conformance/interfaces/mq_timedreceive/8-1.c b/conformance/interfaces/mq_timedreceive/8-1.c index 1b27b0f..e2fb28e 100644 --- a/conformance/interfaces/mq_timedreceive/8-1.c +++ b/conformance/interfaces/mq_timedreceive/8-1.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "posixtest.h" #define TEST "8-1" diff --git a/functional/semaphores/1-1.c b/functional/semaphores/1-1.c new file mode 100755 index 0000000..bc95443 --- /dev/null +++ b/functional/semaphores/1-1.c @@ -0,0 +1,226 @@ +/* + * Author: HongJunxin + * + * Test: Semaphore schedule policy based on priority + * + * Test step: + * 1. Main initilizes semaphore with value 0 + * 2. Main create thread A with low prioriy. A execute sem_wait. + * 3. Main create thread B with middle priority. B execute sem_wait. + * 4. Main create thread C with high priority. C execute sem_wait. + * 5. Main execute sem_post. + * 6. Thread C go ahead from sem_wait and then do sem_post. + * 7. Thread B go ahead from sem_wait and then do sem_post. + * 8. Thread A go ahead from sem_wait and then do sem_post. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "posixtest.h" + +#define THREAD_ENTER 0 +#define THREAD_EXIT 1 + +#define SCHED_POLICY SCHED_RR /* or SCHED_FIFO */ + +static int thread_a_status; +static int thread_b_status; +static int thread_c_status; +static void create_thread(pthread_t *tid, int priority, void *(*fn)(void *)); +static int priority; + +static sem_t sem; + +static void *fn_a(void *arg); +static void *fn_b(void *arg); +static void *fn_c(void *arg); + +static char* get_thread_status(int no); + +int main(int argc, char **argv) +{ + pthread_t thread_a, thread_b, thread_c; + + priority = sched_get_priority_min(SCHED_POLICY); + + if (sem_init(&sem, 0, 0) != 0) { + printf("Test FAILED. Error at sem_init()\n"); + exit(PTS_FAIL); + } + + printf("[Main] create thread A with priority %d\n", priority); + create_thread(&thread_a, priority, fn_a); + + priority += 2; + printf("[Main] create thread B with priority %d\n", priority); + create_thread(&thread_b, priority, fn_b); + + priority += 2; + printf("[Main] create thread C with priority %d\n", priority); + create_thread(&thread_c, priority, fn_c); + + sleep(1); /* To make sure all child thread block on sem_wait() */ + + printf("[Main] sem_post\n"); + if (sem_post(&sem) != 0) { + printf("Test FAILED. Error at sem_post()\n"); + exit(PTS_FAIL); + } + + if (pthread_join(thread_a, NULL) != 0) { + printf("Test FAILED. Error at pthread_join() a\n"); + exit(PTS_FAIL); + } + + if (pthread_join(thread_b, NULL) != 0) { + printf("Test FAILED. Error at pthread_join() b\n"); + exit(PTS_FAIL); + } + + if (pthread_join(thread_c, NULL) != 0) { + printf("Test FAILED. Error at pthread_join() c\n"); + exit(PTS_FAIL); + } + + if (sem_destroy(&sem) != 0) { + printf("Test FAILED. Error at sem_destroy()\n"); + exit(PTS_FAIL); + } + + printf("Test PASSED\n"); + return PTS_PASS; +} + +static void *fn_a(void *arg) +{ + thread_a_status = THREAD_ENTER; + + printf("[Thread A] sem_wait\n"); + if (sem_wait(&sem) != 0) { + printf("Test FAILED. Error at sem_wait() a\n"); + exit(PTS_FAIL); + } + + if (thread_b_status != THREAD_EXIT || + thread_c_status != THREAD_EXIT) { + printf("Test FAILED. Thread B and C should run done before A\n"); + exit(PTS_FAIL); + } + + thread_a_status = THREAD_EXIT; + printf("[Thread A] exit\n"); +} + +static void *fn_b(void *arg) +{ + thread_b_status = THREAD_ENTER; + + printf("[Thread B] sem_wait\n"); + if (sem_wait(&sem) != 0) { + printf("Test FAILED. Error at sem_wait() b\n"); + exit(PTS_FAIL); + } + + if (thread_c_status != THREAD_EXIT || + thread_a_status != THREAD_ENTER) { + printf("Test FAILED. Thread C should run done and thread A should not exit\n"); + printf("[Thread B] thread A status=%s, thread C status=%s\n", + get_thread_status(thread_a_status), get_thread_status(thread_c_status)); + exit(PTS_FAIL); + } + + thread_b_status = THREAD_EXIT; + if (sem_post(&sem) != 0) { + printf("Test FAILED. Error at sem_post() b\n"); + exit(PTS_FAIL); + } + printf("[Thread B] sem_post and exit\n"); +} + +static void *fn_c(void *arg) +{ + thread_c_status = THREAD_ENTER; + + printf("[Thread C] sem_wait\n"); + if (sem_wait(&sem) != 0) { + printf("Test FAILED. Error at sem_wait() c\n"); + exit(PTS_FAIL); + } + + if (thread_b_status == THREAD_EXIT || + thread_a_status == THREAD_EXIT) { + printf("Test FAILED. Thread A and B should run done after C\n"); + exit(PTS_FAIL); + } + + thread_c_status = THREAD_EXIT; + if (sem_post(&sem) != 0) { + printf("Test FAILED. Error at sem_post() c\n"); + exit(PTS_FAIL); + } + printf("[Thread C] sem_post and exit\n"); +} + +static char *get_thread_status(int no) +{ + if (no == THREAD_ENTER) + return "THREAD_ENTER"; + else if (no == THREAD_EXIT) + return "THREAD_EXIT"; + else + return "?Unknown?"; +} + +static void create_thread(pthread_t *tid, int priority, void *(*fn)(void *)) +{ + struct sched_param param; + pthread_attr_t attr; + int ret; + + memset(¶m, 0, sizeof(param)); + memset(&attr, 0, sizeof(attr)); + + if (pthread_attr_init(&attr) != 0) { + printf("Test FAILED. Error at pthread_attr_init()\n"); + exit(PTS_FAIL); + } + + if (pthread_attr_setschedpolicy(&attr, SCHED_POLICY) != 0) { + printf("Test FAILED. Error at pthread_attr_setschedpolicy()\n"); + exit(PTS_FAIL); + } + + if (pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) != 0) { + printf("Test FAILED. Error at pthread_attr_setinheritsched()\n"); + exit(PTS_UNRESOLVED); + } + + param.sched_priority = priority; + if (pthread_attr_setschedparam(&attr, ¶m) != 0) { + printf("Test FAILED. Error at pthread_attr_setschedparam(), errno=%d\n", errno); + exit(PTS_FAIL); + } + + ret = pthread_create(tid, &attr, fn, NULL); + if (ret != 0) { + if (ret == EPERM) { + printf("Test FAILED. Permission Denied when creating" + " thread with policy %d\n", SCHED_POLICY); + exit(PTS_FAIL); + } else { + printf("Test FAILED. Error at pthread_create()\n"); + exit(PTS_FAIL); + } + } + + if (pthread_attr_destroy(&attr) != 0) { + printf("Test FAILED. Error at pthread_attr_destroy()\n"); + exit(PTS_FAIL); + } +} \ No newline at end of file diff --git a/functional/semaphores/1-2.c b/functional/semaphores/1-2.c new file mode 100755 index 0000000..4e8f043 --- /dev/null +++ b/functional/semaphores/1-2.c @@ -0,0 +1,227 @@ +/* + * Author: HongJunxin + * + * Test: Semaphore schedule policy based on waiting time + * tasks with same priority + * + * Test step: + * 1. Main initilizes semaphore with value 0 + * 2. Main create thread A with sched_get_priority_min(). A execute sem_wait. + * 3. Main create thread B with sched_get_priority_min(). B execute sem_wait. + * 4. Main create thread C with sched_get_priority_min(). C execute sem_wait. + * 5. Main execute sem_post. + * 6. Thread A go ahead from sem_wait and then do sem_post. + * 7. Thread B go ahead from sem_wait and then do sem_post. + * 8. Thread C go ahead from sem_wait and then do sem_post. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "posixtest.h" + +#define THREAD_ENTER 0 +#define THREAD_EXIT 1 + +#define SCHED_POLICY SCHED_RR /* or SCHED_FIFO */ + +static int thread_a_status; +static int thread_b_status; +static int thread_c_status; +static void create_thread(pthread_t *tid, int priority, void *(*fn)(void *)); +static int priority; + +static sem_t sem; + +static void *fn_a(void *arg); +static void *fn_b(void *arg); +static void *fn_c(void *arg); + +static char* get_thread_status(int no); + +int main(int argc, char **argv) +{ + pthread_t thread_a, thread_b, thread_c; + + priority = sched_get_priority_min(SCHED_POLICY); + + if (sem_init(&sem, 0, 0) != 0) { + printf("Test FAILED. Error at sem_init()\n"); + exit(PTS_FAIL); + } + + printf("[Main] create thread A with priority %d\n", priority); + create_thread(&thread_a, priority, fn_a); + sleep(1); + + printf("[Main] create thread B with priority %d\n", priority); + create_thread(&thread_b, priority, fn_b); + sleep(1); + + printf("[Main] create thread C with priority %d\n", priority); + create_thread(&thread_c, priority, fn_c); + + sleep(1); /* To make sure all child thread block on sem_wait() */ + + printf("[Main] sem_post\n"); + if (sem_post(&sem) != 0) { + printf("Test FAILED. Error at sem_post()\n"); + exit(PTS_FAIL); + } + + if (pthread_join(thread_a, NULL) != 0) { + printf("Test FAILED. Error at pthread_join() a\n"); + exit(PTS_FAIL); + } + + if (pthread_join(thread_b, NULL) != 0) { + printf("Test FAILED. Error at pthread_join() b\n"); + exit(PTS_FAIL); + } + + if (pthread_join(thread_c, NULL) != 0) { + printf("Test FAILED. Error at pthread_join() c\n"); + exit(PTS_FAIL); + } + + if (sem_destroy(&sem) != 0) { + printf("Test FAILED. Error at sem_destroy()\n"); + exit(PTS_FAIL); + } + + printf("Test PASSED\n"); + return PTS_PASS; +} + +static void *fn_a(void *arg) +{ + thread_a_status = THREAD_ENTER; + + printf("[Thread A] sem_wait\n"); + if (sem_wait(&sem) != 0) { + printf("Test FAILED. Error at sem_wait() a\n"); + exit(PTS_FAIL); + } + + if (thread_b_status == THREAD_EXIT || + thread_c_status == THREAD_EXIT) { + printf("Test FAILED. Thread B and C should run done after A\n"); + exit(PTS_FAIL); + } + + thread_a_status = THREAD_EXIT; + if (sem_post(&sem) != 0) { + printf("Test FAILED. Error at sem_post() b\n"); + exit(PTS_FAIL); + } + printf("[Thread A] sem_post and exit\n"); +} + +static void *fn_b(void *arg) +{ + thread_b_status = THREAD_ENTER; + + printf("[Thread B] sem_wait\n"); + if (sem_wait(&sem) != 0) { + printf("Test FAILED. Error at sem_wait() b\n"); + exit(PTS_FAIL); + } + + if (thread_a_status != THREAD_EXIT || + thread_c_status != THREAD_ENTER) { + printf("Test FAILED. Thread A should run done and thread C should not exit\n"); + printf("[Thread B] thread A status=%s, thread C status=%s\n", + get_thread_status(thread_a_status), get_thread_status(thread_c_status)); + exit(PTS_FAIL); + } + + thread_b_status = THREAD_EXIT; + if (sem_post(&sem) != 0) { + printf("Test FAILED. Error at sem_post() b\n"); + exit(PTS_FAIL); + } + printf("[Thread B] sem_post and exit\n"); +} + +static void *fn_c(void *arg) +{ + thread_c_status = THREAD_ENTER; + + printf("[Thread C] sem_wait\n"); + if (sem_wait(&sem) != 0) { + printf("Test FAILED. Error at sem_wait() c\n"); + exit(PTS_FAIL); + } + + if (thread_b_status != THREAD_EXIT || + thread_a_status != THREAD_EXIT) { + printf("Test FAILED. Thread A and B should run done before C\n"); + exit(PTS_FAIL); + } + + thread_c_status = THREAD_EXIT; + printf("[Thread C] exit\n"); +} + +static char *get_thread_status(int no) +{ + if (no == THREAD_ENTER) + return "THREAD_ENTER"; + else if (no == THREAD_EXIT) + return "THREAD_EXIT"; + else + return "?Unknown?"; +} + +static void create_thread(pthread_t *tid, int priority, void *(*fn)(void *)) +{ + struct sched_param param; + pthread_attr_t attr; + int ret; + + memset(¶m, 0, sizeof(param)); + memset(&attr, 0, sizeof(attr)); + + if (pthread_attr_init(&attr) != 0) { + printf("Test FAILED. Error at pthread_attr_init()\n"); + exit(PTS_FAIL); + } + + if (pthread_attr_setschedpolicy(&attr, SCHED_POLICY) != 0) { + printf("Test FAILED. Error at pthread_attr_setschedpolicy()\n"); + exit(PTS_FAIL); + } + + if (pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) != 0) { + printf("Test FAILED. Error at pthread_attr_setinheritsched()\n"); + exit(PTS_UNRESOLVED); + } + + param.sched_priority = priority; + if (pthread_attr_setschedparam(&attr, ¶m) != 0) { + printf("Test FAILED. Error at pthread_attr_setschedparam(), errno=%d\n", errno); + exit(PTS_FAIL); + } + + ret = pthread_create(tid, &attr, fn, NULL); + if (ret != 0) { + if (ret == EPERM) { + printf("Test FAILED. Permission Denied when creating" + " thread with policy %d\n", SCHED_POLICY); + exit(PTS_FAIL); + } else { + printf("Test FAILED. Error at pthread_create()\n"); + exit(PTS_FAIL); + } + } + + if (pthread_attr_destroy(&attr) != 0) { + printf("Test FAILED. Error at pthread_attr_destroy()\n"); + exit(PTS_FAIL); + } +} \ No newline at end of file diff --git a/functional/semaphores/Makefile b/functional/semaphores/Makefile old mode 100644 new mode 100755 index d944b86..f7a3e32 --- a/functional/semaphores/Makefile +++ b/functional/semaphores/Makefile @@ -5,7 +5,8 @@ LIB= CFLAGS=-Wall -O2 -g all: make-test -make-test: sem_lock.test sem_conpro.test sem_readerwriter.test sem_philosopher.test sem_sleepingbarber.test +make-test: sem_lock.test sem_conpro.test sem_readerwriter.test sem_philosopher.test sem_sleepingbarber.test \ + 1-1.test 1-2.test %.test : %.c $(CC) $(CFLAGS) $(INCLUDE) $< -o $@ $(LIB) -lpthread diff --git a/functional/semaphores/assertions.xml b/functional/semaphores/assertions.xml old mode 100644 new mode 100755 index 8a82510..947c5bf --- a/functional/semaphores/assertions.xml +++ b/functional/semaphores/assertions.xml @@ -14,4 +14,10 @@ Using semaphore to implement philosopher problem Using semaphore to implement sleeping Barber problem + +Test semaphore schedule policy based on priority + + +Test semaphore schedule policy based on waiting time + diff --git a/functional/semaphores/coverage.txt b/functional/semaphores/coverage.txt old mode 100644 new mode 100755 index 3205ea3..2166ffe --- a/functional/semaphores/coverage.txt +++ b/functional/semaphores/coverage.txt @@ -6,3 +6,5 @@ Assertion Covered? 3 YES 4 YES 5 YES +6 YES +7 YES diff --git a/functional/threads/rwlock/1-1.c b/functional/threads/rwlock/1-1.c new file mode 100755 index 0000000..7243524 --- /dev/null +++ b/functional/threads/rwlock/1-1.c @@ -0,0 +1,213 @@ +/* + * Created by: HongJunxin + * This file is licensed under the GPL license. For the full content + * of this license, see the COPYING file at the top level of this + * source tree. + + This program tests pthread_rwlockattr_setkind_np() function. + + Using PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP to initialize rwlock + which prefers to writer. Such rwlock can make sure writer thread has + chance to run in multi-reader scenario. + + Steps: + 1. Main thread initializes rwlock with PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP. + 2. Main thread creates reader thread 1. + 3. Main thread creates writer thread. + 4. Main thread creates reader thread 2. + 5. Reader thread 1 got rwlock and then waiting for reader thread 2 to + tell him go ahead. + 6. Writer thread requires rwlock and then block on it. + 7. Reader thread 2 trys to require rwlock and it fails which is what we expect. + Reader thread 2 tells reader thread 1 to go ahead. Reader thread 2 requires + rwlock and block on it. + 8. Reader thread 1 go ahead and unlocks rwlock. + 9. Writer thread should get rwlock. Writer thread unlocks rwlock. + 10. Reader thread 2 gets rwlock. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "posixtest.h" + + +#define FALSE 0 +#define TRUE 1 + +static pthread_rwlock_t rwlock; +static int rd_1_thread_state; +static int rd_2_thread_state; +static int wr_thread_state; +static int rd_1_pause; + +/* thread states: + 1: not in child thread yet; + 2: just enter child thread ; + 3: just before child thread exit; +*/ + +#define NOT_CREATED_THREAD 1 +#define ENTERED_THREAD 2 +#define EXITING_THREAD 3 + + +static void *fn_wr(void *arg) +{ + wr_thread_state = ENTERED_THREAD; + + printf("[writer thread] require rwlock\n"); + if (pthread_rwlock_wrlock(&rwlock) != 0) { + printf("Error at writer thread pthread_rwlock_wrlock()\n"); + exit(PTS_UNRESOLVED); + } + + printf("[writer thread] got rwlock\n"); + if (rd_2_thread_state == EXITING_THREAD) { + printf("Test FAILED: reader thread 1 has exited when reader thread got rwlock\n"); + exit(PTS_FAIL); + } + + if (pthread_rwlock_unlock(&rwlock) != 0) { + printf("Error at writer thread pthread_rwlock_unlock()\n"); + exit(PTS_UNRESOLVED); + } + + wr_thread_state = EXITING_THREAD; + printf("[writer thread] unlock rwlock\n"); +} + +/* Hold rwlock for a while, to check writer prefered */ +static void *fn_rd_1(void *arg) +{ + rd_1_thread_state = ENTERED_THREAD; + + if (pthread_rwlock_rdlock(&rwlock) != 0) { + printf("Error at read thead 1 pthread_rwlock_unlock()\n"); + exit(PTS_UNRESOLVED); + } + printf("[reader thread 1] got rwlock\n"); + + rd_1_pause = TRUE; + while (rd_1_pause == TRUE); // Wait reader thread 2 to let it go. + + sleep(2); // To make sure reader thread 2 and writer thread are waiting for rwlock + + if (pthread_rwlock_unlock(&rwlock) != 0) { + printf("Error at read thead 1 pthread_rwlock_unlock()\n"); + exit(PTS_UNRESOLVED); + } + printf("[reader thread 1] unlocked rwlock\n"); + + rd_1_thread_state = EXITING_THREAD; +} + +static void *fn_rd_2(void *arg) +{ + int ret; + rd_2_thread_state = ENTERED_THREAD; + + printf("[reader thread 2] try to get rwlock\n"); + ret = pthread_rwlock_tryrdlock(&rwlock); + if (ret == 0) { + printf("Test FAILED: reader thread 2 got the rwlock, but" + " writer thread is still waiting for it \n"); + exit(PTS_FAIL); + } else if (ret == EBUSY) { + printf("[reader thread 2] tryrdlock() return EBUSY which we expect.\n"); + } else { + printf("Error at pthread_rwlock_tryrdlock()\n"); + exit(PTS_UNRESOLVED); + } + + rd_1_pause = FALSE; + + printf("[reader thread 2] require rwlock\n"); + if (pthread_rwlock_rdlock(&rwlock) != 0) { + printf("Error at reader thread 2 pthread_rwlock_rdlock()\n"); + exit(PTS_UNRESOLVED); + } + + // double check + printf("[reader thread 2] got rwlock\n"); + if (wr_thread_state != EXITING_THREAD) { + printf("Test FAILD: reader thread 2 got rwlock, but writer thread" + " not exiting\n"); + exit(PTS_FAIL); + } + + if (pthread_rwlock_unlock(&rwlock) != 0) { + printf("Error at reader thread 2 pthread_rwlock_unlock()\n"); + exit(PTS_UNRESOLVED); + } + + rd_2_thread_state = EXITING_THREAD; + printf("[reader thread 2] unlock rwlock\n"); +} + +static void pthread_join_fn(pthread_t t) +{ + if (pthread_join(t, NULL) != 0) { + printf("Error at pthread_join()\n"); + exit(PTS_UNRESOLVED); + } +} + +int main(int argc, char **argv) +{ + pthread_rwlockattr_t attr; + pthread_t rd_1_thread, rd_2_thread, wr_thread; + + if (pthread_rwlockattr_init(&attr) != 0) { + printf("Error at pthread_rwlockattr_init()\n"); + return PTS_UNRESOLVED; + } + + /* PTHREAD_RWLOCK_PREFER_WRITER_NP not work for writer-prefered, but + PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP can do it. */ + + pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); + + if (pthread_rwlock_init(&rwlock, &attr) != 0) { + printf("Error at pthread_rwlock_init()\n"); + return PTS_UNRESOLVED; + } + + if (pthread_rwlockattr_destroy(&attr) != 0) { + printf("Error at pthread_rwlockattr_destroy()\n"); + return PTS_UNRESOLVED; + } + + printf("[main] create reader thread 1\n"); + if (pthread_create(&rd_1_thread, NULL, fn_rd_1, NULL) != 0) { + printf("[main] Error at reader thread 1 pthread_create()\n"); + return PTS_UNRESOLVED; + } + + sleep(1); // Make sure reader thread 1 got rwlock + + printf("[main] create writer thread\n"); + if (pthread_create(&wr_thread, NULL, fn_wr, NULL) != 0) { + printf("[main] Error at writer thread pthread_create()\n"); + return PTS_UNRESOLVED; + } + + sleep(1); // Make sure writer thread is waitting for rwlock + + printf("[main] create reader thread 2\n"); + if (pthread_create(&rd_2_thread, NULL, fn_rd_2, NULL) != 0) { + printf("[main] Error at reader thread 2 pthread_create()\n"); + return PTS_UNRESOLVED; + } + + pthread_join_fn(rd_1_thread); + pthread_join_fn(wr_thread); + pthread_join_fn(rd_2_thread); + + printf("Test PASSED\n"); + return PTS_PASS; +} \ No newline at end of file diff --git a/functional/threads/rwlock/Makefile b/functional/threads/rwlock/Makefile new file mode 100755 index 0000000..a9aa17e --- /dev/null +++ b/functional/threads/rwlock/Makefile @@ -0,0 +1,28 @@ +# Copyright (c) 2004, Intel Corporation. All rights reserved. +# Created by: HongJunxin +# This file is licensed under the GPL license. For the full content +# of this license, see the COPYING file at the top level of this +# source tree. + +INCLUDE = -Wall -I../../../include + +CFLAGS = + +LDFLAGS = -lpthread + +SRC = $(wildcard *.c) +OBJ = $(SRC:%.c=%.test) + +all: do_compile + +do_compile: $(OBJ) + +%.test: %.c + $(CC) $(CFLAGS) $(INCLUDE) $< -o $@ $(LDFLAGS) + +clean: + @rm -f $(OBJ) + + @if test -z "$(CC)"; then \ + CC=gcc; \ + fi diff --git a/functional/threads/schedule/1-3.c b/functional/threads/schedule/1-3.c new file mode 100755 index 0000000..474eab0 --- /dev/null +++ b/functional/threads/schedule/1-3.c @@ -0,0 +1,264 @@ +/* + * Created by: HongJunxin + * This file is licensed under the GPL license. For the full content + * of this license, see the COPYING file at the top level of this + * source tree. + * + * Test avoidance of prioriy reversal + * + * Test steps: + * 1. Main initializes mutex mtx with PTHREAD_PRIO_INHERIT property + * 2. Main creates thread B using SCHED_FIFO, low priority. + * 3. Main creates thread A using SCHED_FIFO, high priority. + * 4. Main creates thread C using SCHED_FIFO, middle priority. + * 5. Thread A B C run in the same cpu + * 6. Thread B get mutex and then fall into while loop + * 7. Thread A acquire mutex and block on it. + * 8. Thread C is suspended waitting for thread B run done + * 9. Thread B quit while loop and release mutex + * 10. Thread A get mutex and then run done + * 11. Thread C run done + * 12. Thread B run done + */ + + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include "posixtest.h" + +#define TRD_POLICY SCHED_FIFO +#define RUNNING 0 +#define RUN_DONE 1 +#define FALSE 0 +#define TURE 1 + +static pthread_mutex_t mtx; +static int is_thread_c_pause; +static int a_thread_status; +static int c_thread_status; + +static int single_cpu = FALSE; + +static int set_cpu_affinity(int cpu_no) +{ + int ret; + cpu_set_t set; + CPU_ZERO(&set); + CPU_SET(cpu_no, &set); + ret = sched_setaffinity((pid_t)0, sizeof(set), &set); + if (ret != 0) { + printf("Error at sched_setaffinity()\n"); + exit(PTS_UNRESOLVED); + } + + return 0; +} + +static void *fn_a(void *arg) +{ + int s; + + a_thread_status = RUNNING; + if (single_cpu == FALSE) + set_cpu_affinity(1); + + printf("[Thread A] acquires mutex\n"); + s = pthread_mutex_lock(&mtx); + if (s != 0) { + printf("[Thread A] failed to lock mutex, error code=%d\n", s); + exit(PTS_UNRESOLVED); + } + + s = pthread_mutex_unlock(&mtx); + if (s != 0) { + printf("[Thread A] failed to unlock mutex, error code=%d\n", s); + exit(PTS_UNRESOLVED); + } + + a_thread_status = RUN_DONE; + printf("[Thread A] run done\n"); +} + +static void *fn_b(void *arg) +{ + int s; + + if (single_cpu == FALSE) + set_cpu_affinity(1); + + printf("[Thread B] acquires mutex\n"); + s = pthread_mutex_lock(&mtx); + if (s != 0) { + printf("[Thread B] failed to lock mutex, error caode=%d\n", s); + exit(PTS_UNRESOLVED); + } + + while (is_thread_c_pause); + + /* If the priority of thread B didn't be raised, thread C (with middle priority) + run done already. Because the priority of thread B has been raised (higher than C) + and it is running, so in this time point thread C should be in suspended. */ + if (c_thread_status == RUN_DONE) { + printf("Test FAILED. Thread C shouldn't run done, because thread B" + " has higher priority than it now and still in running.\n"); + exit(PTS_FAIL); + } + + printf("[Thread B] unlock mutex\n"); + s = pthread_mutex_unlock(&mtx); + if (s != 0) { + printf("[Thread B] failed to unlock mutex, error code=%d\n", s); + exit(PTS_UNRESOLVED); + } + printf("[Thread B] run done\n"); +} + +static void *fn_c(void *arg) +{ + int s; + + if (single_cpu == FALSE) + set_cpu_affinity(1); + + c_thread_status = RUNNING; + printf("[Thread C] running...\n"); + + c_thread_status = RUN_DONE; + printf("[Thread C] run done\n"); +} + +static void create_thread(pthread_t *tid, int priority, void *(*fn)(void *)) +{ + struct sched_param param; + pthread_attr_t attr; + int ret; + + memset(¶m, 0, sizeof(param)); + memset(&attr, 0, sizeof(attr)); + + if (pthread_attr_init(&attr) != 0) { + printf("Test FAILED. Error at pthread_attr_init()\n"); + exit(PTS_FAIL); + } + + if (pthread_attr_setschedpolicy(&attr, TRD_POLICY) != 0) { + printf("Test FAILED. Error at pthread_attr_setschedpolicy()\n"); + exit(PTS_FAIL); + } + + /* PTHREAD_EXPLICIT_SCHED need root. Default is PTHREAD_INHERIT_SCHED which + make child thread inherit parent attribute. */ + if (pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) != 0) { + printf("Test FAILED. Error at pthread_attr_setinheritsched()\n"); + exit(PTS_UNRESOLVED); + } + + param.sched_priority = priority; + if (pthread_attr_setschedparam(&attr, ¶m) != 0) { + printf("Test FAILED. Error at pthread_attr_setschedpolicy()\n"); + exit(PTS_FAIL); + } + + ret = pthread_create(tid, &attr, fn, NULL); + if (ret != 0) { + if (ret == EPERM) { + printf("Test FAILED. Permission Denied when creating" + " thread with policy %d\n", TRD_POLICY); + exit(PTS_FAIL); + } else { + printf("Test FAILED. Error at pthread_create()\n"); + exit(PTS_FAIL); + } + } + + if (pthread_attr_destroy(&attr) != 0) { + printf("Test FAILED. Error at pthread_attr_destroy()\n"); + exit(PTS_FAIL); + } +} + +static void init_mutex(pthread_mutex_t *mutex) +{ + int ret; + pthread_mutexattr_t mta; + + ret = pthread_mutexattr_init(&mta); + if (ret != 0) { + printf("Error at pthread_mutexattr_init()\n"); + exit(PTS_FAIL); + } + + /* mutex protocol should be set to PTHREAD_PRIO_INHERIT */ + ret = pthread_mutexattr_setprotocol(&mta, PTHREAD_PRIO_INHERIT); + if (ret != 0) { + printf("Error at pthread_mutexattr_setprotocol()\n"); + exit(PTS_FAIL); + } + + ret = pthread_mutex_init(mutex, &mta); + if (ret != 0) { + printf("Error at pthread_mutex_init()\n"); + exit(PTS_FAIL); + } + + if(pthread_mutexattr_destroy(&mta) != 0) { + printf("Error at pthread_mutexattr_destroy()\n"); + exit(PTS_FAIL); + } +} + +int main() +{ + int priority; + int policy; + int cpu_num; + pthread_t a_thread, b_thread, c_thread; + + cpu_num = sysconf(_SC_NPROCESSORS_CONF); + if (cpu_num == 1) + single_cpu = TURE; + + init_mutex(&mtx); + + priority = sched_get_priority_min(TRD_POLICY); + printf("[Main] create B thread, with priority: %d\n", priority); + is_thread_c_pause = 1; + create_thread(&b_thread, priority, fn_b); + + priority = sched_get_priority_min(TRD_POLICY) + 6; + printf("[Main] create A thread, with priority: %d\n", priority); + create_thread(&a_thread, priority, fn_a); + + priority = sched_get_priority_min(TRD_POLICY) + 2; + printf("[Main] create C thread, with priority: %d\n", priority); + create_thread(&c_thread, priority, fn_c); + + sleep(1); // Make sure all thread are running + + is_thread_c_pause = 0; + + if (pthread_join(b_thread, NULL) != 0) { + printf("Error at pthread_join()\n"); + return PTS_UNRESOLVED; + } + + if (pthread_join(a_thread, NULL) != 0) { + printf("Error at pthread_join()\n"); + return PTS_UNRESOLVED; + } + + if (pthread_join(c_thread, NULL) != 0) { + printf("Error at pthread_join()\n"); + return PTS_UNRESOLVED; + } + + printf("Test PASS.\n"); + return PTS_PASS; +} \ No newline at end of file diff --git a/functional/threads/schedule/1-4.c b/functional/threads/schedule/1-4.c new file mode 100644 index 0000000..9b67add --- /dev/null +++ b/functional/threads/schedule/1-4.c @@ -0,0 +1,264 @@ +/* + * Created by: HongJunxin + * This file is licensed under the GPL license. For the full content + * of this license, see the COPYING file at the top level of this + * source tree. + * + * Test SCHED_FIFO and SCHED_RR + * + * Test SCHED_FIFO if TRD_POLICY is set to SCHED_FIFO + * Test SCHED_RR if TRD_POLICY is set to SCHED_RR + * + * Test steps: + * Main create two thread with same priority and run in the same cpu. + * + * Expectation: + * If schedule is SCHED_FIFO + * Thread A should run done at first and then thread B begin running. + * + * If schedule id SCHED_RR + * Thread A and B running rotational + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include "posixtest.h" + + +#define TRD_POLICY SCHED_FIFO +#define TEST_COUNT 1 +#define RUNNING 0 +#define RUN_DONE 1 + +#define FALSE 0 +#define TURE 1 + +static void create_thread(pthread_t *tid, int priority, void *(*fn)(void *)); +static int set_cpu_affinity(int cpu_no); +static void *fn_a(void *arg); +static void *fn_b(void *arg); +static char *get_thread_status(int no); +static char *get_schedule(int no); + +extern int errno; + +static int task_a_status; +static int task_b_status; +static int single_cpu = FALSE; + + +int main(int argc, char **argv) +{ + pthread_t task_a, task_b; + int i; + int a_priority = 1; + int b_priority = 1; + int cpu_num; + + cpu_num = sysconf(_SC_NPROCESSORS_CONF); + if (cpu_num == 1) + single_cpu = TURE; + + for (i=0; i