-
Notifications
You must be signed in to change notification settings - Fork 0
[GUIDE] Structs
Após alguns meses desenvolvendo em Python, meu cérebro passou a pensar de maneira mais orientada a objetos. O que pode ser bom num projeto desse tamanho, mas pode atrapalhar caso você leve isso longe demais.
Nós queremos um projeto estruturado com boa encapsulação de dados, e não exatamente Orientado a Objeto.
Criei 5 structs:
- t_coder
- t_simulation
- t_heap_node
- t_heap
- t_dongle
t_coder contém todas as variáveis relevantes para os coders, sua thread (pthread_t), dongle direito e esquerdo, ponteiros para mutexes necessários e um ponteiro *sim para um t_simulation.
t_simulation contém todas as variáveis relevantes para a simulação no geral. Também tem uma thread (pthread_t), mas tem número de coders, os mutexes, que os coders apontam para, etc.
t_heap é a priority queue, contém *nodes (t_heap_nodes), que é um array de todos os nós, tamanho, capacidade e um ponteiro para uma função que recebe dois heap nodes e retorna um int. Essa função é importante porque é usada como regra principal de ordenação na priority queue. Caso o programa esteja rodando em FIFO, a função que o ponteiro aponta é a função que compara em FIFO, se não, será a função que compara em EDF. Basicamente, é a função que decide quem vai primeiro e quem vai por último.
t_heap_node é um nó na t_heap, um coder na fila. Contém um ponteiro para o coder que está na fila, prioridade e seq, que é um contador que é dado a cada node, coder que entra na fila, e incrementa a cada novo node. Seq serve de fallback em casos de empate de prioridade.
t_dongle representa o estado de um dongle. Contém id, condicional para saber se está ocupado ou livre, quanto tempo até que esteja livre novamente, um mutex (necessário para a cond) e um pthread_cond_t, que permite que uma thread espere até que uma condição seja verdadeira. Nesse caso, o cond é o que vai permitir a thread entrar em sleep e acordar quando o dongle desejado estiver livre. É uma variável perfeita para gerenciar filas de espera.
Caso esteja um pouco nebuloso, aqui estão os structs para referência:
typedef struct s_heap_node
{
t_coder *coder;
long priority;
long seq;
} t_heap_node;
typedef struct s_heap
{
t_heap_node *nodes;
int size;
int capacity;
int (*cmp)(t_heap_node *, t_heap_node *);
} t_heap;
typedef struct s_dongle
{
int id;
int taken;
long available_after;
pthread_mutex_t mutex;
pthread_cond_t cond;
t_heap *wait_queue;
} t_dongle;
typedef struct s_coder
{
pthread_t thread;
int id;
int is_compiling;
int compiling_score;
long last_compile;
t_dongle *r_dongle;
t_dongle *l_dongle;
pthread_mutex_t *dead_lock;
pthread_mutex_t *compile_lock;
pthread_mutex_t *print_lock;
t_simulation *sim;
} t_coder;
typedef struct s_simulation
{
pthread_t thread;
int nb_of_coders;
long start_time;
int dead_flag;
pthread_mutex_t dead_lock;
pthread_mutex_t compile_lock;
pthread_mutex_t print_lock;
long time_to_burnout;
long time_to_compile;
long time_to_debug;
long time_to_refactor;
int compiling_quota;
long dongle_cooldown;
char *scheduler;
t_coder *coders;
t_dongle *dongles;
} t_simulation;