-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy paththread.h
161 lines (134 loc) · 3.84 KB
/
thread.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#ifndef thread_h
#define thread_h
#include "cpu.h"
#include "traits.h"
#include "debug.h"
#include "list.h"
#include <ctime>
#include <chrono>
__BEGIN_API
class Thread
{
protected:
typedef CPU::Context Context;
public:
typedef Ordered_List<Thread> Ready_Queue;
// Thread State
enum State {
RUNNING,
READY,
SUSPENDED,
FINISHING,
WAITING
};
/*
* Construtor vazio. Necessário para inicialização, mas sem importância para a execução das Threads.
*/
Thread() { }
/*
* Cria uma Thread passando um ponteiro para a função a ser executada
* e os parâmetros passados para a função, que podem variar.
* Cria o contexto da Thread.
* PS: devido ao template, este método deve ser implementado neste mesmo arquivo .h
*/
template<typename ... Tn>
Thread(void (* entry)(Tn ...), Tn ... an);
/*
* Retorna a Thread que está em execução.
*/
static Thread * running() { return _running; }
/*
* Método para trocar o contexto entre duas thread, a anterior (prev)
* e a próxima (next).
* Deve encapsular a chamada para a troca de contexto realizada pela class CPU.
* Valor de retorno é negativo se houve erro, ou zero.
*/
static int switch_context(Thread * prev, Thread * next);
/*
* Termina a thread.
* exit_code é o código de término devolvido pela tarefa (ignorar agora, vai ser usado mais tarde).
* Quando a thread encerra, o controle deve retornar à main.
*/
void thread_exit (int exit_code);
/*
* Retorna o ID da thread.
*/
int id();
/*
* Despachante (dispatcher) de threads.
* Executa enquanto houverem threads do usuário.
* Chama o escalonador para definir a próxima tarefa a ser executada.
*/
static void dispatcher();
/*
* Realiza a inicialização da class Thread.
* Cria as Threads main e dispatcher.
*/
static void init(void (*main)(void *));
/*
* Devolve o processador para a thread dispatcher que irá escolher outra thread pronta
* para ser executada.
*/
static void yield();
/*
* Suspende a thread em execução até que a thread "alvo" finalize.
*/
int join();
/*
* Suspende a thread até que resume() seja chamado.
*/
void suspend();
/*
* Coloca uma Thread que estava suspensa de volta para a fila de prontos.
*/
void resume();
/*
* Coloca a thread para dormir
*/
void sleep();
/*
* Acorda uma thread que estava dormindo
*/
void wakeup();
/*
* Destrutor de uma thread. Realiza todos os procedimentos para manter a consistência da classe.
*/
~Thread();
/*
* Qualquer outro método que você achar necessário para a solução.
*/
Context * context();
Ready_Queue::Element * link();
private:
unsigned int _id;
bool _call_join;
Context * volatile _context;
static Thread * _running;
static Thread _main;
static CPU::Context _main_context;
static Thread _dispatcher;
static Ready_Queue _ready;
static Ready_Queue _suspended;
Ready_Queue::Element _link;
volatile State _state;
/*
* Qualquer outro atributo que você achar necessário para a solução.
*/
static unsigned int _thread_count;
int _exit_code;
};
template<typename ... Tn>
inline Thread::Thread(void (* entry)(Tn ...), Tn ... an)
: _link(this, (std::chrono::duration_cast<std::chrono::microseconds>
(std::chrono::high_resolution_clock::now().time_since_epoch()).count()))
{
db<Thread>(TRC) << "Thread " << _thread_count << " created.\n";
_context = new CPU::Context(entry, an ...);
_id = Thread::_thread_count++;
//_exit_code = id - 1;
if (_id > 0)
_ready.insert_tail(&_link);
_state = READY;
}
__END_API
#endif