forked from justellie/ProyectoSO
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdefiniciones.h
335 lines (283 loc) · 12.8 KB
/
definiciones.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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
/**
* @file definiciones.h
* @brief Definiciones de los tipos de datos y las referencia de las variables globales usadas dentro del programa.
* @author Todos
* @version 0.2.0.6
* @date 2021-03-04
*/
#ifndef __DEFINICIONES_H__
#define __DEFINICIONES_H__
#define MAX_ATENCION 5 ///< Maximo número de pacientes que pueden atender.
#define NHOSPITALES 3 ///< Maximo número de pacientes.
#define NPACIENTES 10 ///< Se asume un número máximo de pacientes en el sistema.
#define NMEDICOS 20 ///< Se asume un número máximo de médicos a nivel nacional.
#define NENFERMERAS 25 ///< Se asume un número máximo de enfermeras a nivel nacional.
#define NANALISTAS (NHOSPITALES * NSALA_MUESTRA)
// Más gestores por cada hospital.
// NOTE: posiblemente sólo se necesite uno de ellos, no estoy seguro.
#define NVOLUNTARIOS 5 ///< Cuántos voluntarios hay en el país
#define NACTUALIZACIONES 2 ///< Cuántas veces se actualizan las estadísticas de la UGC.
#define NSALA_ESPERA 20 ///< núm. de puestos en la sala de espera.
#define NSALA_MUESTRA 5 ///< núm. de habitaciones de toma de muestras.
#define NLOTE_PCR 30 ///< núm. de PCR que se solicitan por vez
#define NMIN_PCR 5 ///< núm. mínimo de PCR en el hospital antes de pedir otro lote
// ---------------------------
#define NCAMAS_CENTINELA 25 ///< núm. de camas por hospital centinela.
#define NCAMAS_INTERMEDIO 20 ///< núm. de camas por hospital intermedio.
#define NCAMAS_GENERAL 15 ///< núm. de camas por hospital general.
#define NCAMAS_UGC 200 ///< núm. de camas ugc.
#define PORCENTAJE_INT_CENTINELA 0.20 ///< porcentaje de camas intensivas por hospital centinela.
#define PORCENTAJE_INT_INTERMEDIO 0.15 ///< porcentaje de camas intensivas por hospital intermedio.
#define PORCENTAJE_INT_GENERAL 0.05 ///< porcentaje de camas intensivas por hospital general.
// ---------------------------
#include <stdbool.h>
#include <errno.h>
#include <math.h> // Requires -lm
// [T] Tipos de datos -------------
#include "Tipos/RefMap.h"
#include "Tipos/RefQueue.h"
// --------------------------------
// [>] POSIX ----------------------
#include <pthread.h>
#include <semaphore.h>
typedef pthread_mutex_t Mutex; ///< Alias para facilitar las declaraciones.
typedef pthread_cond_t Condicion; ///< Alias para facilitar las declaraciones.
typedef pthread_barrier_t Barrier; ///< Alias para facilitar las declaraciones.
// --------------------------------
// [*] PERSONAL:
typedef enum { Ninguno, EnCasa, Basica, Intensivo, Muerto} TipoAtencion; ///< Tipo de atención que debe recibir el paciente.
typedef enum { PidePCR , PideTanque, PideRespirador,PideEnfermera,PideMedico} Recurso; ///< Tipo de Petición de recursos.
typedef enum { Medico , Enfermera } TipoPersonal; ///< Diferencia el personal del hospital.
typedef enum { test=1} MuestraPcr; ///< Tipo de datos de las muestras PCR
typedef enum { dummyTanque } TanqueDato; ///< Tipo de datos que representa los tanques de oxígeno.
typedef enum { dummyRespirador } Respirador; ///< Tipo de datos que representa los respiradores del hospital.
/// Representa al recurso Personal del hospital. Puede ser Médico o enfermera.
/// Según su ocupación y el servicio que atienden, estarán supervisando a un número
/// determinado de pacientes.
typedef struct {
int id;
TipoPersonal tipo;
} Personal;
void construirPersonal( Personal* p , int id , TipoPersonal profesion );
void destruirPersonal ( Personal* p );
// [*] PACIENTE:
typedef struct {
int id;
int vivo;
int deAlta;
int fueAtendido;
int ingresando;
int tiene_cama;
TipoAtencion servicio;
// Uno de cada uno a la vez. ni más, ni menos.
int medID[MAX_ATENCION]; // TODO: Verificar el número de médicos.
int enfID[MAX_ATENCION]; //
Mutex medLock;
Mutex enfLock;
//Mutex dondeLock;
sem_t muestraTomada;
Mutex atendidoLock; // Permita pausar el hilo actor_paciente
Condicion atendido; // mientras espera por ser atendido por algún
// Médico/Enfermero ó Voluntario.
} Paciente;
void construirPaciente( Paciente* p , int id );
void destruirPaciente ( Paciente* p );
// [*] HOSPITAL:
//Permite llevar el conteo de los movimientos de los pacientes
typedef struct {
int muertos;
int hospitalizados;
int dadosDeAlta;
int monitoreados;
int covid;
}Estadistica;
// medicos y pacientes deben ser diccionarios de la forma:
// { (TipoPersonal,id) : Personal }
typedef enum { Centinela , Intermedio , General } TipoHospital;
// Agrupa ciertos campos de una vez.
typedef struct {
int ncamasBas;
int ncamasInt;
int nenfermeras;
int nmedicos;
int ntanques;
int nrespira;
} TuplaRecursos;
typedef struct {
// NOTE: El personal estára dividido por grados de disponibilidad.
// Para reservar, se debe extraer algún profesional del nivel más alto
// de disponibilidad. Si no hay ninguno, se buscará en el nivel inferior.
// ``` mi_medico = extraer de medicos[MAX_ATENCION-1]```
//
// Luego, se deberá colocar a ése profesional en el grupo de menor
// disponibilidad.
// ``` colocar mi_medico en medicos[MAX_ATENCION-2] ```
//
// Se realizará esto hasta llegar al último nivel (0) del cual, no será
// posible extraer a nadie. En tal caso, debe reportarse que ha ocurrido un
// error. y manejarlo según corresponda.
RefMap medicos [MAX_ATENCION];
RefMap enfermeras[MAX_ATENCION];
RefQueue pacientesEnSilla;
// TODO: ^^^ Inicializar ambos grupos de diccionarios.
// >>> Se indexarán por su id. <<<
// NOTE: No se necesita saber cuántos hay
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// IDEA(sGaps): Se puede usar la tupla (servicio,id) para organizar al personal.
// Suponiendo que:
// ```
// MEDICOS = medicos[disponibilidad_actual]
// ```
//
// Se podría insertar un elemento con `refmap_put( MEDICOS , &un_medico , &un_medico );`
// + Al crear al RefMap, se pasa una función de comparación que aplique un cast desde `void*` a `Personal*`
// ```
// void cmp_por_servicio_id( void* p1 , void* p2 ){
// Personal *x = p1 , *y= p2;
// int result = cmp(x->servicio,y->servicio);
// return (result == IGUALES)? cmp(x->id,y->id) : result; }
// ```
// + Se pasa también una función de copia que devuelva la función identidad.
// `void sin_copiar( void* key ){ return key; }`
// + Se pasa una función de liberación que no haga nada:
// `void no_borrar( void* key ){ return NULL; }`
//
// ¿Por qué usar sin_copiar/borrar? El RefMap copiará la clave, pero esta existe dentro de cada
// personal. Como cada miembro es inicializado en el programa principal, no se puede borrar ningún
// dato del mismo desde aquí (no es la responsabilidad del hospital ni de los gestores).
//
// Para remover un elemento (AKA: reservar), se podría usar:
// `un_medico = refmap_extract_min_if_key( MEDICOS , EXTRAER_SI_BASICO );`
// para pedir algún médico del servicio básico y
// `un_medico = refmap_extract_min_if_key( MEDICOS , EXTRAER_SI_INTENSIVO );`
//
Estadistica estadis_pacientes;
RefQueue pacientes;
sem_t salaEspera;
sem_t salaMuestra;
int id;
TipoHospital tipo;
sem_t camasBasico;
sem_t camasIntensivo;
RefQueue tanquesOxigeno;
RefQueue respiradores;
RefQueue PCR;
RefQueue reporte;
Condicion stast;
TuplaRecursos estadis_recursos; // Se actualizan siempre (incremento en valores), pero son reiniciadas
Mutex estadisticasLock; // 2 veces al día. Por ello usan un seguro de escritura/lectura
// (Así como en base de datos)
} Hospital;
void construirHospital( Hospital* h , int id , TipoHospital tipo , int camasInt , int camasBas );
void destruirHospital ( Hospital* h );
// [*] INVENTARIO UGC:
// Inventario de Transferencias de la UGC
typedef struct {
// Todos los recursos a disposición:
sem_t camasBasico;
sem_t camasIntensivo;
sem_t tanquesOxigeno;
sem_t respiradores;
// TODO: convertir ambos a mutex
Mutex espera_personal;
Mutex EsperandoPorRecurso;
// TODO: Inicializar primero antes de usar.
// Todos están disponibles.
RefQueue medicos;
RefQueue enfermeras;
RefQueue pacientes;
RefQueue voluntarios;
RefQueue peticiones;
RefQueue peticionesPersonal;
TuplaRecursos estadisticas[NACTUALIZACIONES];
Mutex estadisticasLock;
int turno; // Indica cuál tabla de estadisticas se debe leer
Mutex turnoLock; // Una vez que se necesite actualizar, simplemente se pasará al valor
// turno = (turno+1) % NACTUALIZACIONES;
Condicion FinalizarStat;
int continuar;
Mutex FinalizarStatLock;
int days;
} UGC;
void construirUGC( UGC* ugc , TuplaRecursos* descripcion );
void destruirUGC ( UGC* ugc );
void asignarMedicosUGC ( UGC* ugc , Personal medicos[] , long n );
void asignarEnfermerasUGC( UGC* ugc , Personal enfermeras[] , long n );
// Tupla de peticion a inventario.
typedef struct {
int idHospital;
Recurso tipo_recurso;
int cantidad;
} TuplaInventario;
// [*] GESTOR DE CAMA:
// Agilizan los procesos para dar de alta al paciente.
// verifican el estado del paciente. y sus días de estancia.
typedef struct {
int id;
Hospital* hospital;
} GestorCama;
void construirGestorCama( GestorCama* g , int id , Hospital* hospital );
void destruirGestorCama ( GestorCama* g );
// [*] VOLUNTARIO:
// Similar al gestor de cama, pero fuera del hospital.
typedef struct {
int id;
} Voluntario;
void construirVoluntario( Voluntario* v , int id );
void destruirVoluntario ( Voluntario* v );
typedef struct {
int id;
Hospital* refHospital;
pthread_mutex_t espera;
}jefe_uci;
void construirJefeUCI( jefe_uci* j , int id , Hospital* h );
void destruirJefeUCI ( jefe_uci* j );
//RefQueue pacienteEnCasa;
// referencias globales que se puedan alcanzar desde
// cualquier hilo.
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// ---- Tablas Globales ----
// NOTE: Tdos requieren de inicializacion
//Paciente Tabla_Pacientes[NPACIENTES];
//Personal Tabla_Medicos[NMEDICOS];
//Personal Tabla_Enfermeras[NENFERMERAS];
//Hospital Tabla_Hospitales[NHOSPITALES];
//GestorCama Tabla_Gestores[NHOSPITALES];
//Voluntario Tabla_Voluntarios[NVOLUNTARIOS];
void inicializarPacientes();
void inicializarMedicos();
void inicializarEnfermeras();
void inicializarHospitales( float porc_centinelas, float porc_intermedio , float porc_general );
void inicializarPacientesEnCasa();
void inicializarVoluntarios();
void inicializarGestorCama();
void inicializarJefeUCI();
void borrarPacientes();
void borrarMedicos();
void borrarEnfermeras();
void borrarHospitales();
void borrarPacientesEnCasa();
void borrarVoluntarios();
void borrarGestorCama();
void borrarJefeUCI();
TipoAtencion obtener_diagnostico_simple();
TipoAtencion obtener_diagnostico_compuesta(void *paciente);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// [@] Sincronizacion global ---------
extern Barrier Paso_Inicializacion;
extern Condicion FinalizarAhora;
extern int Continuar;
extern Mutex FinalizarAhoraLock;
// [+] Tablas globales de Datos -----------------
extern Paciente Tabla_Pacientes[NPACIENTES];
extern Personal Tabla_Medicos[NMEDICOS];
extern Personal Tabla_Enfermeras[NENFERMERAS];
extern Hospital Tabla_Hospitales[NHOSPITALES];
extern GestorCama Tabla_Gestores[NHOSPITALES];
extern jefe_uci Tabla_JefeUCI [NHOSPITALES];
extern Voluntario Tabla_Voluntarios[NVOLUNTARIOS];
extern UGC gestor_central;
extern Estadistica statHospital[NACTUALIZACIONES][NHOSPITALES];
// [*] Voluntarios -----------
extern RefQueue pacienteEnCasa;
#endif