1//------------------------------------------------------------------------------
2// Copyright (c) 2016 by Lukasz Janyst <lukasz@jany.st>
3//------------------------------------------------------------------------------
4// This file is part of thread-bites.
5//
6// thread-bites is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10//
11// thread-bites is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with thread-bites. If not, see <http://www.gnu.org/licenses/>.
18//------------------------------------------------------------------------------
19
20#include <tb.h>
21#include <string.h>
22
23//------------------------------------------------------------------------------
24// Policy to string
25//------------------------------------------------------------------------------
26const char *strpolicy(int policy)
27{
28 switch(policy)
29 {
30 case SCHED_NORMAL: return "SCHED_NORMAL";
31 case SCHED_FIFO: return "SCHED_FIFO";
32 case SCHED_RR: return "SCHED_RR";
33 default: return "UNKNOWN";
34 }
35}
36
37//------------------------------------------------------------------------------
38// Thread function
39//------------------------------------------------------------------------------
40void *thread_func(void *arg)
41{
42 tbthread_t self = tbthread_self();
43 int policy, priority;
44 tbthread_getschedparam(self, &policy, &priority);
45 tbprint("[thread 0x%llx] Started. Policy: %s, priority: %d\n", self,
46 strpolicy(policy), priority);
47 for(uint64_t i = 0; i < 5000000000ULL; ++i);
48 tbprint("[thread 0x%llx] Done. Policy: %s, priority: %d\n", self,
49 strpolicy(policy), priority);
50 return 0;
51}
52
53//------------------------------------------------------------------------------
54// Run the threads
55//------------------------------------------------------------------------------
56int run(tbthread_attr_t attr[10])
57{
58 tbprint("Testing policy: %s\n", strpolicy(attr[0].sched_policy));
59 tbthread_t thread[10];
60 int st = 0;
61 for(int i = 0; i < 10; ++i) {
62 st = tbthread_create(&thread[i], &attr[i], thread_func, 0);
63 if(st != 0) {
64 tbprint("Failed to spawn thread %d: %s\n", i, tbstrerror(-st));
65 return st;
66 }
67 }
68
69 tbprint("[thread main] Threads spawned successfully\n");
70
71 for(int i = 0; i < 10; ++i) {
72 st = tbthread_join(thread[i], 0);
73 if(st != 0) {
74 tbprint("Failed to join thread %d: %s\n", i, tbstrerror(-st));
75 return st;
76 }
77 }
78
79 tbprint("[thread main] Threads joined\n");
80 tbprint("---\n");
81 return 0;
82}
83//------------------------------------------------------------------------------
84// Start the show
85//------------------------------------------------------------------------------
86int main(int argc, char **argv)
87{
88 tbthread_init();
89 tbthread_attr_t attr[10];
90 int st = 0;
91
92 //----------------------------------------------------------------------------
93 // Warn about not being root
94 //----------------------------------------------------------------------------
95 if(SYSCALL0(__NR_getuid) != 0)
96 tbprint("[!!!] You should run this test as root\n");
97
98 //----------------------------------------------------------------------------
99 // Run the threads with normal policy
100 //----------------------------------------------------------------------------
101 for(int i = 0; i < 10; ++i)
102 tbthread_attr_init(&attr[i]);
103
104 if((st = run(attr)))
105 goto exit;
106
107 //----------------------------------------------------------------------------
108 // Run the threads with FIFO policy
109 //----------------------------------------------------------------------------
110 tbthread_setschedparam(tbthread_self(), SCHED_FIFO, 99);
111 for(int i = 0; i < 10; ++i) {
112 int priority = 10-i/3;
113 tbthread_attr_setschedpolicy(&attr[i], SCHED_FIFO);
114 tbthread_attr_setschedpriority(&attr[i], priority);
115 tbthread_attr_setinheritsched(&attr[i], TBTHREAD_EXPLICIT_SCHED);
116 }
117
118 if((st = run(attr)))
119 goto exit;
120
121exit:
122 tbthread_finit();
123 return st;
124};
125