This repository has been archived by the owner on May 11, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
srpt.sh
1589 lines (1524 loc) · 60 KB
/
srpt.sh
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
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#! /bin/bash
# Simula la ejeución de una serie de procesos en un algoritmo SRPT
# AUTHOR: Rodrigo Díaz, Diego González
# LICENSE: MIT
if ! [[ (${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -eq 3 && ${BASH_VERSINFO[2]} -ge 48) || (${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -gt 3) || ${BASH_VERSINFO[0]} -gt 4 ]]; then read -n 1 -p "VERSIÓN DE BASH < 4.3.48, la ejecución en esta versión no ha sido testeada, ¿continuar (s/n)? "; [[ ! $REPLY =~ ^[SsYy] ]] && echo && exit 90; fi
if [[ $(tput cols) -lt 100 ]]; then read -n 1 -p "El programa esta diseñado para funcionar con una ventana de al menos 100 caracteres de ancho, ¿continuar (s/n)? "; [[ ! $REPLY =~ ^[SsYy] ]] && echo && exit 91; fi
#_____________________________________________
# COMIENZO DE FUNCIONES
#_____________________________________________
#######################################
# Muestra cabeceras gráficas
# Globales:
# mem_tamano
# mem_tamano_abreviacion
# mem_tamano_redondeado
# mem_usada
# mem_usada_abreviacion
# mem_usada_redondeado
# modo_silencio
# proc_count
# proc_count_abreviacion
# proc_count_redondeado
# tiempo
# Argumentos:
# modo:
# 0 = linea separación
# 1 = cabecera principal
# 2 = cabecera secundaria
# salida:
# 0 = pantalla y log
# 1 = pantalla
# 2 = log
# Devuelve:
# Texto
#######################################
function header() {
local -ri modo=$1 salida=$2
local linea linea_no_esc linea_buffer
if [[ $modo -eq 0 ]]; then
linea=
linea_no_esc=
for i in {17..21} {21..17} ; do
linea+="\e[38;5;${i}m##########"
linea_no_esc+='##########'
done
if [[ $salida -eq 0 ]]; then
pantalla "$linea"; log 3 "$linea" "$linea_no_esc"
elif [[ $salida -eq 1 ]]; then
pantalla "$linea"
else
log 3 "$linea" "$linea_no_esc"
fi
elif [[ $modo -eq 1 ]]; then
linea=
if [[ -z $modo_silencio ]]; then clear && clear; fi
header 0 $salida
linea='\e[38;5;17m#\e[0m \e[48;5;17m ALGORITMO SRPT, PAGINACIÓN FIFO, MEMORIA CONTINUA Y REUBICABLE\e[0m \e[38;5;17m#'
pantalla "$linea"
else
header 1 $salida
linea='\e[38;5;17m#\e[0m \e[48;5;17mMemoria: '
if [[ -z $mem_usada_abreviacion ]]; then
linea+=$(printf " %3d/" "$mem_usada_redondeado")
else
linea+=$(printf "%3d%1s/" "$mem_usada_redondeado" "$mem_usada_abreviacion")
fi
if [[ -z $mem_tamano_abreviacion ]]; then
linea+=$(printf "%3d\e[0m " "$mem_tamano_redondeado")
else
linea+=$(printf "%3d%1s\e[0m" "$mem_tamano_redondeado" "$mem_tamano_abreviacion")
fi
linea+=$(printf " \e[48;5;17mTiempo: %3d\e[0m \e[48;5;17mNúmero de Procesos: " "$tiempo")
if [[ -z $proc_count_abreviacion ]]; then
linea+=$(printf " %3d" "$proc_count_redondeado")
else
linea+=$(printf "%3d%1s" "$proc_count_redondeado" "$proc_count_abreviacion")
fi
linea+='\e[0m \e[38;5;17m#'
pantalla "$linea"
log 3 "$(printf "\e[38;5;17m#\e[39m%42sINSTANTE: %3d%43s\e[38;5;17m#\e[39m" " " "$tiempo" " ")" "$(printf "#%42sINSTANTE: %3d%43s#" " " "$tiempo" " ")"
header 0
fi
}
#######################################
# Solicita datos al usuario
# Globales:
# mem_tamano
# proc_color
# proc_color_secuencia
# proc_count
# proc_estado
# proc_id
# proc_pagina_tamano
# proc_paginas
# proc_tamano
# proc_tiempo_ejecucion
# proc_tiempo_ejecucion_esperado
# proc_tiempo_ejecucion_restante
# proc_tiempo_llegada
# tiempo_final
# Argumentos:
# Nada
# Devuelve:
# Nada
#######################################
function pedirDatos() {
local -i i finalizado
pantalla
if [[ -z $proc_color_secuencia ]]; then
proc_color_secuencia=(1,0 2,0 3,0 4,0 5,0 6,0 7,0 23,0 88,0 92,0 123,0 147,0 202,0 222,0 243,0)
fi
if [[ -z $mem_tamano ]]; then #si el tamaño de memoria nulo
until [[ $mem_tamano =~ ^[0-9]+$ ]] && [[ ! $mem_tamano -eq 0 ]]; do #hasta el tamaño de memoria empiece entre 0 y 9 Y sea diferente a 0 hacer...
printf "\e[1A%80s\r" " " #imprimir 80 espacios en color 1A
read -p "Tamaño (en marcos) de la memoria: " mem_tamano #te pide que escribas algo y eso eso va a ser el tamaño de memoria
printf "\e[91mINTRODUCE UN NÚMERO SUPERIOR A 0\e[39m\r" #te muestra en pantalla el texto y vuelve a la linea anterior
done
printf "%*s\n" "$(tput cols)" " "
fi
if [[ -z $proc_pagina_tamano ]]; then
until [[ $proc_pagina_tamano =~ ^[0-9]+$ ]] && [[ ! $proc_pagina_tamano -eq 0 ]]; do
printf "\e[1A%80s\r" " "
read -p "Direcciones por página: " proc_pagina_tamano
printf "\e[91mINTRODUCE UN NÚMERO SUPERIOR A 0\e[39m\r"
done
printf "%*s\n" "$(tput cols)" " "
fi
if [[ -z $proc_id ]]; then
for ((i=0; finalizado!=1; i++)); do
until [[ ${proc_tamano[i]} =~ ^[0-9]+$ ]] && [[ ! ${proc_tamano[i]} -eq 0 ]] || [[ $finalizado -eq 1 ]]; do
printf "\e[1A%80s\r" " "
read -p "[P${i}] Marcos de página: " proc_tamano[$i]
if [[ -z ${proc_tamano[i]} ]]; then finalizado=1; unset proc_tamano[$i]; fi
printf "\e[91mINTRODUCE UN NÚMERO SUPERIOR A 0\e[39m\r"
done
printf "%*s\n" "$(tput cols)" " "
until [[ ${proc_tiempo_llegada[i]} =~ ^[0-9]+$ ]] || [[ $finalizado -eq 1 ]]; do
printf "\e[1A%80s\r" " "
read -p "[P${i}] Tiempo de llegada: " proc_tiempo_llegada[$i]
if [[ -z ${proc_tiempo_llegada[i]} ]]; then
finalizado=1
unset proc_tamano[$i]
unset proc_tiempo_llegada[$i]
fi
printf "\e[91mINTRODUCE UN NÚMERO SUPERIOR A 0\e[39m\r"
done
printf "%*s\n" "$(tput cols)" " "
until [[ -n ${proc_direcciones[i]} ]] || [[ $finalizado -eq 1 ]]; do
printf "\e[1A%80s\r" " "
read -p "[P${i}] Secuencia de direcciones: " proc_direcciones[$i]
proc_direcciones[$i]=$(echo ${proc_direcciones[i]} | tr -d ' ')
if [[ -z ${proc_direcciones[i]} ]]; then
finalizado=1
unset proc_tamano[$i]
unset proc_tiempo_llegada[$i]
unset proc_direcciones[$i]
fi
if [[ ${proc_direcciones[i]} =~ ([0-9]+,)*[0-9]+ ]]; then
proc_direcciones[$i]="${BASH_REMATCH[0]}"
else
unset proc_direcciones[$i]
fi
if [[ -z ${proc_direcciones[i]} ]]; then
printf "\e[91mINTRODUCE NÚMEROS SEPARADOS POR COMAS\e[39m\r"
fi
done
printf "%*s\n" "$(tput cols)" " "
if [[ -z $finalizado ]]; then
printf "%*s\r" "$(tput cols)" " "
proc_paginas[$i]=$(convertirDireccion ${proc_direcciones[i]})
proc_id[$i]="P${i}" #Si no tiene la id asignada le da una
proc_estado[$i]=1
if [[ $i -lt ${#proc_color_secuencia[@]} ]]; then
proc_color[$i]="48;5;$(echo ${proc_color_secuencia[i]} | cut -d ',' -f2);38;5;$(echo ${proc_color_secuencia[i]} | cut -d ',' -f1)"
else
proc_color[$i]="48;5;$(shuf -i 0-256 -n 1);38;5;$(shuf -i 0-256 -n 1)"
fi
proc_tiempo_ejecucion[$i]=0
proc_tiempo_ejecucion_esperado[$i]=$(echo ${proc_paginas[i]} | tr ',' ' ' | wc -w) #Asigna el tiempo rastante al numero de paginas
proc_tiempo_ejecucion_restante[$i]=${proc_tiempo_ejecucion_esperado[i]}
log 3 "Proceso \e[44m${i}\e[49m, con ID \e[44m${proc_id[i]}\e[49m, Secuencia \e[44m${proc_paginas[i]}\e[49m, Marcos \e[44m${proc_tamano[i]}\e[49m, Llegada \e[44m${proc_tiempo_llegada[i]}" "Proceso <${i}>, con ID <${proc_id[i]}>, Secuencia <${proc_paginas[i]}>, Marcos <${proc_tamano[i]}>, Llegada <${proc_tiempo_llegada[i]}>"
else
echo -ne '\e[1A'
read -n 1 -p "Terminar introducción de datos (s/n)? "
printf "\r%80s" " "
if [[ ! $REPLY =~ ^[SsYy] ]]; then
unset finalizado
((i--))
fi
fi
done
proc_count=${#proc_id[@]}
if [[ $proc_count -eq 0 ]]; then
finalizarEjecucion 21
fi
fi
tiempo_final="$(ultimoTiempo)"
}
#######################################
# Lee argumentos de ejecución
# Globales:
# filename
# mem_tamano
# modo_debug
# modo_silencio
# nivel_log
# proc_count
# tiempo_break
# tiempo_unbreak
# Argumentos:
# -b TIEMPO
# Habilita modo debug en TIEMPO
# -d
# Habilita modo debug
# -f FILENAME
# Cargar datos desde FILENAME
# -l NIVEL
# Nivel de salida por fichero:
# 0 debug
# 1 extendido
# 2 estructural
# 3 por defecto
# 4 alertas
# 5 mínimo
# 9 ejecición
# 10 deshabilitado
# -m MARCOS
# Tamaño de memoria en marcos
# -p NÚMERO
# Número de procesos
# -s
# Deshabilita salida por pantalla
# -u TIEMPO
# Deshabilita modo debug en TIEMPO
# Devuelve:
# Nada
#######################################
function leerArgs() {
while [[ $1 != "" ]]; do #mientras el parametro 1 no esté vacio
case $1 in
-s|--silencio) #si el parametro es s o silencio
modo_silencio=1
log 3 'Salida gráfica deshabilitada' '@';;
-d|--debug)
modo_debug=1
nivel_log=0
log 3 'Entrando modo debug' '@';;
-f|--filename)
if [[ -n $2 ]] && [[ ! $2 == -* ]]; then
filename=$2
log 5 "Argumento de archivo introducido \e[44m$filename" "Argumento de archivo introducido <${filename}>"
shift 2
continue
else
echo 'ERROR: "--filename" requiere un argumento válido/no vacio.'
log 9 '\e[91m!!!\e[39m El argumento \e[91mfilename\e[39m contiene errores \e[91m!!!\e[39m' '!!! El argumento filename contiene errores !!!'
finalizarEjecucion 40
fi;;
-m|--memoria)
if [[ -n $2 ]] && [[ ! $2 == -* ]]; then
local -ri tmp_mem_tamano=$2
log 5 "Argumento de memoria introducido \e[44m$tmp_mem_tamano" "Argumento de memoria introducido ${tmp_mem_tamano}"
shift 2
continue
else
echo 'ERROR: "--memoria" requiere un argumento válido/no vacio.'
log 9 '\e[91m!!!\e[39m El argumento \e[91mmemoria\e[39m contiene errores \e[91m!!!\e[39m' '!!! El argumento memoria contiene errores !!!'
finalizarEjecucion 41
fi;;
-p|--procesos)
if [[ -n $2 ]] && [[ ! $2 == -* ]]; then
proc_count=$2
log 5 "Argumento de procesos introducido \e[44m$proc_count" "Argumento de procesos introducido <${proc_count}>"
shift 2
continue
else
echo 'ERROR: "--procesos" requiere un argumento válido/no vacio.'
log 9 '\e[91m!!!\e[39m El argumento \e[91mprocesos\e[39m contiene errores \e[91m!!!\e[39m' '!!! El argumento procesos contiene errores !!!'
finalizarEjecucion 42
fi;;
-l|--log)
if [[ -n $2 ]] && [[ ! $2 == -* ]]; then
nivel_log=$2
log 5 "Establecido nivel de log a \e[44m$nivel_log" "Establecido nivel de log a <${nivel_log}>"
shift 2
continue
else
echo 'ERROR: "--log" requiere un argumento válido/no vacio.'
log 9 '\e[91m!!!\e[39m El argumento \e[91mlog\e[39m contiene errores \e[91m!!!\e[39m' '!!! El argumento log contiene errores !!!'
finalizarEjecucion 43
fi;;
-b|--breakpoint)
if [[ -n $2 ]] && [[ ! $2 == -* ]]; then
tiempo_break=$2
log 9 "Estableciendo breakpoint en \e[44m$tiempo_break" "Estableciendo breakpoint en <${tiempo_break}>"
shift 2
continue
else
echo 'ERROR: "--breakpoint" requiere un argumento válido/no vacio.'
log 9 '\e[91m!!!\e[39m El argumento \e[91mbreakpoint\e[39m contiene errores \e[91m!!!\e[39m' '!!! El argumento breakpoint contiene errores !!!'
finalizarEjecucion 44
fi;;
-u|--unbreakpoint)
if [[ -n $2 ]] && [[ ! $2 == -* ]]; then
tiempo_unbreak=$2
log 9 "Estableciendo unbreakpoint en \e[44m$tiempo_unbreak" "Estableciendo unbreakpoint en <${tiempo_unbreak}>"
shift 2
continue
else
echo 'ERROR: "--unbreakpoint" requiere un argumento válido/no vacio.'
log 9 '\e[91m!!!\e[39m El argumento \e[91munbreakpoint\e[39m contiene errores \e[91m!!!\e[39m' '!!! El argumento unbreakpoint contiene errores !!!'
finalizarEjecucion 45
fi;;
-?*)
log 4 "\e[93m^^^\e[39m Opcíon \e[44m${1}\e[49m desconocida \e[93m^^^\e[39m" "^^^ Opción ${1} desconocida ^^^";;
*)
break
esac
shift
done
if [[ -n "$filename" ]]; then
log 3 "Leyendo archivo:" '@'
leerArchivo
log 0 "Fin Lectura archivo" '@'
fi
if [[ -n "$tmp_mem_tamano" ]]; then
mem_tamano=$tmp_mem_tamano
log 3 "Tamaño de memoria asignado a \e[44m$mem_tamano" "Tamaño de memoria asignado a <${mem_tamano}>"
fi
}
#######################################
# Lee datos de archivo
# Globales:
# filename
# mem_tamano
# proc_color
# proc_color_secuencia
# proc_count
# proc_estado
# proc_id
# proc_pagina_tamano
# proc_paginas
# proc_tamano
# proc_tiempo_ejecucion
# proc_tiempo_ejecucion_esperado
# proc_tiempo_ejecucion_restante
# proc_tiempo_llegada
# tiempo_final
# Argumentos:
# Nada
# Devuelve:
# Nada
#######################################
function leerArchivo() {
local -i i=0
if [[ ! -f $filename ]]; then
echo "Archivo \"${filename}\" no válido."
log 9 '\e[91m!!!\e[39m El archivo no existe \e[91m!!!\e[39m' '!!! El archivo no existe !!!'
finalizarEjecucion 30
fi
IFS=$'\n'; set -f #Establece el valor de separacion como final de linea
for line in $(<$filename); do
line=$(echo $line | cut -d '#' -f1 | tr -d ' ' | tr -d '\r') #elimina los espacios (-d) y tr sustituye
log 0 "Linea leida \e[44m$line" "Linea leida <${line}>"
if [[ ! $line == +* ]] && [[ -n $line ]]; then #si la linea no empieza por # y + o no es nula entonces...
proc_tamano[$i]=$(echo $line | cut -d ';' -f1) #guarda el tamaño, porque va cortando todolo separado por ; y coge la 1ª columna(-f1)
proc_direcciones[$i]=$(echo $line | cut -d ';' -f2) #guarda las paginas
proc_tiempo_llegada[$i]=$(echo $line | cut -d ';' -f3) #guarda el tiempo de llegada
proc_id[$i]=$(echo $line | cut -d';' -f4) #guarda la id
if [[ $i -lt ${#proc_color_secuencia[@]} ]]; then
proc_color[$i]="48;5;$(echo ${proc_color_secuencia[$i]} | cut -d ',' -f2);38;5;$(echo ${proc_color_secuencia[$i]} | cut -d ',' -f1)"
else
proc_color[$i]="48;5;$(shuf -i 0-256 -n 1);38;5;$(shuf -i 0-256 -n 1)"
fi
log 0 'Es proceso:'
log 0 "Tamaño \e[44m${proc_tamano[$i]}" "Tamaño <${proc_tamano[$i]}>"
log 0 "Secuecia \e[44m${proc_paginas[$i]}" "Secuecia <${proc_paginas[$i]}>"
log 0 "Llegada \e[44m${proc_tiempo_llegada[$i]}" "Llegada <${proc_tiempo_llegada[$i]}>"
log 0 "ID \e[44m${proc_id[$i]}" "ID <${proc_id[$i]}>"
if [[ -z ${proc_id[$i]} ]]; then
proc_id[$i]="P${i}" #si el proceso no tiene id se le asigna uno por defecto
log 0 "Nueva ID \e[44m${proc_id[$i]}" "Nueva ID <${proc_id[$i]}>"
fi
proc_estado[$i]=1
proc_paginas[$i]=$(convertirDireccion ${proc_direcciones[$i]})
proc_tiempo_ejecucion_esperado[$i]=$(echo ${proc_paginas[i]} | tr ',' ' ' | wc -w)
proc_tiempo_ejecucion_restante[$i]=${proc_tiempo_ejecucion_esperado[i]}
log 3 "Proceso \e[44m${i}\e[49m, con ID \e[44m${proc_id[$i]}\e[49m, Secuencia \e[44m${proc_paginas[$i]}\e[49m, Marcos \e[44m${proc_tamano[$i]}\e[49m, Llegada \e[44m${proc_tiempo_llegada[$i]}\e[49m" "Proceso <${i}>, con ID <${proc_id[$i]}>, Secuencia <${proc_paginas[$i]}>, Marcos <${proc_tamano[$i]}>, Llegada <${proc_tiempo_llegada[$i]}>"
((i++))
else
if [[ $line == +* ]]; then
log 0 'Es opción:' '@'
case $(echo $line | tr -d '+' | cut -d ':' -f1) in
"MEMORIA")
mem_tamano=$(echo $line | cut -d ':' -f2)
log 0 "de memoria \e[44m$mem_tamano" "de memoria <${mem_tamano}>"
log 3 "Configuración, marcos de memoria \e[44m$mem_tamano" "Configuración, marcos de memoria <${mem_tamano}>";;
"DIRECCIONES")
proc_pagina_tamano=$(echo $line | cut -d ':' -f2)
log 0 "de página \e[44m$proc_pagina_tamano" "de página <${proc_pagina_tamano}>"
log 3 "Configuración, tamaño de pagina \e[44m$proc_pagina_tamano" "Configuración, tamaño de pagina <${proc_pagina_tamano}>";;
"COLORES")
IFS=';' read -r -a proc_color_secuencia <<< "$(echo $line | cut -d ':' -f2)"
log 0 "de color \e[44m$proc_color_secuencia" "de página <${proc_color_secuencia}>"
log 3 "Configuración, colores \e[44m$proc_color_secuencia" "Configuración, colores <${proc_color_secuencia}>";;
*)
echo 'CONFIGURACIÓN EN FICHERO NO VÁLIDA'
log 9 "\e[91m!!!\e[39m Configuración en archivo no válida \e[91m!!!\e[39m" "!!! Configuración en archivo no válida !!!"
finalizarEjecucion 31;;
esac
else log 0 'Es comentario' '@'; fi
fi
done
set +f; unset IFS
if [[ ! $i -eq 0 ]]; then
proc_count=$i
fi
}
#######################################
# Convierte páginas a direcciones
# Globales:
# proc_pagina_tamano
# Argumentos:
# direcciones
# Devuelve:
# paginas
#######################################
function convertirDireccion() {
local -r secuencia=$1
local -a direcciones=()
local paginas
IFS=',' read -r -a direcciones <<< "$secuencia"
for direccion in ${direcciones[@]}; do
paginas+="$((direccion / proc_pagina_tamano)),"
done
echo "${paginas::-1}"
}
#######################################
# Muestra datos por pantalla
# Globales:
# linea_tiempo
# mem_paginas
# mem_paginas_secuencia
# mem_proc_id
# mem_proc_index
# mem_siguiente_ejecucion
# out_proc_index
# proc_color
# proc_estado
# proc_id
# proc_orden
# proc_paginas
# proc_posicion
# proc_tamano
# proc_tiempo_ejecucion
# proc_tiempo_ejecucion_esperado
# proc_tiempo_ejecucion_restante
# proc_tiempo_espera
# proc_tiempo_respuesta
# swp_proc_id
# swp_proc_index
# tiempo
# Argumentos:
# Nada
# Devuelve:
# Nada
#######################################
function salidaEjecucion() {
local -i i j ultimo_cambio=0 offset
local -a paginas paginas_color
local id estado estado_color linea linea_no_esc linea_buffer posicion fallo
header 2
linea='\e[38;5;17m#\e[39m ID T.LL T.Ej Mrcos Estd T.Rst T.CPU T.Esp T.Rsp Pos Paginas \e[38;5;17m#\e[39m'
linea_no_esc='# ID T.LL T.Ej Mrcos Estd T.Rst T.CPU T.Esp T.Rsp Pos Paginas #'
pantalla "$linea"; log 3 "$linea" "$linea_no_esc"
for i in ${proc_orden[@]}; do
id=${proc_id[$i]:0:8}
if [[ ${proc_estado[i]} -ge 16 ]]; then
estado='FINL'
estado_color='96'
elif [[ ${proc_estado[i]} -ge 8 ]]; then
estado='EJEC'
estado_color='95'
elif [[ ${proc_estado[i]} -ge 4 ]]; then
estado='MEM '
estado_color='92'
elif [[ ${proc_estado[i]} -ge 2 ]]; then
estado='ESPR'
estado_color='93'
else
estado='NOLL'
estado_color='91'
fi
for ((j=-5; j<=6; j++)); do
if [[ $j -ge 0 ]]; then
if [[ $((proc_tiempo_ejecucion[i]+j)) -lt ${proc_tiempo_ejecucion_esperado[i]} ]]; then
paginas[$j]=$(echo ${proc_paginas[i]} | cut -d ',' -f $((proc_tiempo_ejecucion[i]+j+1)))
paginas_color[$j]="${proc_color[i]}"
else
paginas[$j]=
paginas_color[$j]=
fi
elif [[ ${proc_tiempo_ejecucion[i]} -ge $((-j)) ]]; then
paginas[$((9-j))]=$(echo ${proc_paginas[i]} | cut -d ',' -f $((proc_tiempo_ejecucion[i]+j+1)))
posicion="${i},$((proc_tiempo_ejecucion[i]+j)),p"
fallo="${proc_paginas_evolucion["$posicion"]}"
if [[ ! -z $fallo ]] && [[ $fallo -ge 0 ]]; then
paginas_color[$((9-j))]="7;${proc_color[i]}"
else
paginas_color[$((9-j))]="${proc_color[i]}"
fi
else
paginas[$((9-j))]=
paginas_color[$((9-j))]=
fi
done
linea=$(printf "\e[38;5;17m#\e[39m \e[%sm%*s\e[0m%*s \e[%sm%3d\e[0m \e[%sm%3d\e[0m \e[%sm%3d\e[0m \e[%sm%s\e[0m \e[%sm%3d\e[0m \e[%sm%3d\e[0m \e[%sm%3d\e[0m \e[%sm%3d\e[0m \e[%sm%3d\e[0m \e[%sm%2s\e[0m \e[%sm%2s\e[0m \e[%sm%2s\e[0m \e[%sm%2s\e[0m \e[%sm%2s\e[0m \e[4;%sm%2s\e[0m \e[%sm%2s\e[0m \e[%sm%2s\e[0m \e[%sm%2s\e[0m \e[%sm%2s\e[0m \e[%sm%2s\e[0m \e[%sm%2s\e[0m \e[38;5;17m#\e[39m" "${proc_color[i]}" "$(((${#id}+8)/2))" "$id" "$((5-${#id}/2))" " " "${proc_color[i]}" "${proc_tiempo_llegada[i]}" "${proc_color[i]}" "${proc_tiempo_ejecucion_esperado[i]}" "${proc_color[i]}" "${proc_tamano[i]}" "$estado_color" "$estado" "${proc_color[i]}" "${proc_tiempo_ejecucion_restante[i]}" "${proc_color[i]}" "${proc_tiempo_ejecucion[i]}" "${proc_color[i]}" "${proc_tiempo_espera[i]}" "${proc_color[i]}" "${proc_tiempo_respuesta[i]}" "${proc_color[i]}" "$(echo ${proc_posicion[i]} | cut -d ' ' -f1)" "${paginas_color[14]}" "${paginas[14]}" "${paginas_color[13]}" "${paginas[13]}" "${paginas_color[12]}" "${paginas[12]}" "${paginas_color[11]}" "${paginas[11]}" "${paginas_color[10]}" "${paginas[10]}" "${paginas_color[0]}" "${paginas[0]}" "${paginas_color[1]}" "${paginas[1]}" "${paginas_color[2]}" "${paginas[2]}" "${paginas_color[3]}" "${paginas[3]}" "${paginas_color[4]}" "${paginas[4]}" "${paginas_color[5]}" "${paginas[5]}" "${paginas_color[6]}" "${paginas[6]}")
linea_no_esc=$(printf "# %*s%*s %3d %3d %3d %s %3d %3d %3d %3d %3d %2s %2s %2s %2s %2s>%2s<%2s %2s %2s %2s %2s %2s #" "$(((${#id}+8)/2))" "$id" "$((5-${#id}/2))" " " "${proc_tiempo_llegada[i]}" "${proc_tiempo_ejecucion_esperado[i]}" "${proc_tamano[i]}" "$estado" "${proc_tiempo_ejecucion_restante[i]}" "${proc_tiempo_ejecucion[i]}" "${proc_tiempo_espera[i]}" "${proc_tiempo_respuesta[i]}" "$(echo ${proc_posicion[i]} | cut -d ' ' -f1)" "${paginas[14]}" "${paginas[13]}" "${paginas[12]}" "${paginas[11]}" "${paginas[10]}" "${paginas[0]}" "${paginas[1]}" "${paginas[2]}" "${paginas[3]}" "${paginas[4]}" "${paginas[5]}" "${paginas[6]}")
pantalla "$linea"; log 3 "$linea" "$linea_no_esc"
done
header 0
linea='\e[38;5;17m#\e[39m '; linea_no_esc='# '
for i in {0..31}; do
offset=$(echo ${proc_posicion[mem_paginas[i]]} | cut -d ' ' -f1)
if [[ -n ${mem_paginas[i]} ]] && [[ ${mem_paginas[i]} -ne $((mem_paginas[i-1])) ]]; then
ultimo_cambio=0
fi
if [[ -n ${mem_paginas[i]} ]] && [[ $i -lt $mem_tamano ]]; then
if [[ $i -eq $((proc_paginas_apuntador[mem_paginas[i]] + offset)) ]]; then
linea+=" \e[${proc_color[${mem_paginas[i]}]}mv\e[0m "; linea_no_esc+=' v '
else
((++ultimo_cambio))
id=$(echo ${proc_id[mem_paginas[i]]} | cut -c $(($ultimo_cambio * 3 - 2))-)
linea_buffer=$(printf "%-3s" "${id:0:3}")
linea+="\e[${proc_color[mem_paginas[i]]}m$linea_buffer\e[0m"; linea_no_esc+="$linea_buffer"
fi
else
linea+=' '; linea_no_esc+=' '
fi
done
linea+=' \e[38;5;17m#\e[39m'; linea_no_esc+=' #'
pantalla "$linea"; log 3 "$linea" "$linea_no_esc"
ultimo_cambio=0
linea='\e[38;5;17m#\e[39m '; linea_no_esc='# '
for i in {0..31}; do
if [[ $i -lt $mem_tamano ]]; then
if [[ $i -ne 0 ]] && ([[ ${mem_paginas[i]} -ne ${mem_paginas[((i - 1))]} ]] || ([[ -z ${mem_paginas[i]} ]] && [[ -n ${mem_paginas[((i - 1))]} ]])); then
case $i in
0|1|26|27) linea+='\e[38;5;17m';;
[2-4]|[23-25]) linea+='\e[38;5;18m';;
[5-7]|[20-22]) linea+='\e[38;5;19m';;
*) linea+='\e[38;5;20m';;
esac
linea+='|'; linea_no_esc+='|'
else
linea+=' '; linea_no_esc+=' '
fi
if [[ -z ${mem_paginas[$i]} ]]; then
linea+='\e[38;5;236m##\e[0m'; linea_no_esc+='##'
elif [[ ${mem_paginas_secuencia[i]} -eq -1 ]]; then
linea+="\e[${proc_color[${mem_paginas[i]}]}m##\e[0m"; linea_no_esc+='##'
else
linea+="$(printf "\e[${proc_color[${mem_paginas[i]}]}m%2d\e[0m" "${mem_paginas_secuencia[i]}")"; linea_no_esc+="$(printf "%2d" "${mem_paginas_secuencia[i]}")"
fi
else
linea+=' '; linea_no_esc+=' '
fi
done
linea+=' \e[38;5;17m#\e[39m'; linea_no_esc+=' #'
pantalla "$linea"; log 3 "$linea" "$linea_no_esc"
linea='\e[38;5;17m#\e[39m '; linea_no_esc='# '
for i in {0..31}; do
if [[ $i -lt $mem_tamano ]]; then
linea+="$(printf " %2d" "$i")"; linea_no_esc+="$(printf " %2d" "$i")"
else
linea+=' '; linea_no_esc+=' '
fi
done
linea+=' \e[38;5;17m#\e[39m'; linea_no_esc+=' #'
pantalla "$linea"; log 3 "$linea" "$linea_no_esc"
header 0
linea='\e[38;5;17m#\e[39m '; linea_no_esc='# '
for ((i=tiempo-41; i<tiempo; i++)); do
if [[ $i -ge 0 ]] && [[ ${linea_tiempo[i]} -ne -1 ]]; then
if [[ $i -gt 0 ]] && [[ ${linea_tiempo[i]} -eq ${linea_tiempo[((i-1))]} ]]; then
((++ultimo_cambio))
else
ultimo_cambio=0
fi
if [[ $ultimo_cambio -eq 0 ]]; then
linea+="\e[${proc_color[linea_tiempo[i]]}m| "; linea_no_esc+='| '
elif [[ $((ultimo_cambio * 2 -2)) -lt ${#proc_id[linea_tiempo[i]]} ]]; then
id=$(echo ${proc_id[linea_tiempo[i]]} | cut -c $(($ultimo_cambio * 2 - 1))-)
linea_buffer=$(printf "%-2s" "${id:0:2}")
linea+="\e[${proc_color[linea_tiempo[i]]}m$linea_buffer"; linea_no_esc+="$linea_buffer"
else
linea+='\e[0m '; linea_no_esc+=' '
fi
else
linea+=' '; linea_no_esc+=' '
fi
done
linea+='\e[0m| proceso \e[38;5;17m#\e[39m'; linea_no_esc+='| proceso #'
pantalla "$linea"; log 3 "$linea" "$linea_no_esc"
linea='\e[38;5;17m#\e[39m '; linea_no_esc='# '
for ((i=tiempo-41; i<tiempo; i++)); do
if [[ $i -ge 0 ]] && [[ ${linea_tiempo[i]} -ne -1 ]]; then
linea+="\e[${proc_color[${linea_tiempo[$i]}]}m=="; linea_no_esc+='=='
else
linea+='\e[49;38;5;237m--'; linea_no_esc+='--'
fi
done
linea+='\e[49;38;5;236m----------->\e[0m \e[38;5;17m#\e[39m'; linea_no_esc+='-----------> #'
pantalla "$linea"; log 3 "$linea" "$linea_no_esc"
ultimo_cambio=0
linea='\e[38;5;17m#\e[39m '; linea_no_esc='# '
for ((i=tiempo-41; i<tiempo; i++)); do
if [[ $i -ge 0 ]] && [[ ${linea_tiempo[i]} -ne -1 ]]; then
if [[ $i -gt 0 ]] && [[ ${linea_tiempo[i]} -eq ${linea_tiempo[((i-1))]} ]]; then
((++ultimo_cambio))
else
ultimo_cambio=0
fi
if [[ $ultimo_cambio -eq 0 ]]; then
linea+="\e[${proc_color[linea_tiempo[i]]}m| "; linea_no_esc+='| '
elif [[ $((ultimo_cambio * 2 -2)) -lt ${#i} ]]; then
id=$(echo $((i-1)) | cut -c $(($ultimo_cambio * 2 - 1))-)
linea_buffer=$(printf "%-2s" "${id:0:2}")
linea+="\e[${proc_color[linea_tiempo[i]]}m$linea_buffer"; linea_no_esc+="$linea_buffer"
else
linea+='\e[0m '; linea_no_esc+=' '
fi
else
linea+=' '; linea_no_esc+=' '
fi
done
linea_buffer=$(printf "\e[0m| %-3s tiempo " "$tiempo")
linea+="$linea_buffer\e[38;5;17m#\e[39m"; linea_no_esc+="$linea_buffer#"
pantalla "$linea"; log 3 "$linea" "$linea_no_esc"
header 0
}
#######################################
# Realiza un paso de tiempo
# Globales:
# evento
# evento_log
# evento_log_NoEsc
# mem_proc_id
# mem_tamano
# mem_tamano_abreviacion
# mem_tamano_redondeado
# mem_usada
# mem_usada_abreviacion
# mem_usada_redondeado
# modo_debug
# modo_silencio
# proc_count
# proc_count_abreviacion
# proc_count_redondeado
# swp_proc_id
# tiempo
# tiempo_break
# tiempo_final
# tiempo_unbreak
# Argumentos:
# Nada
# Devuelve:
# Nada
#######################################
function step() {
local -i i
if [[ $tiempo -le $tiempo_final ]]; then poblarSwap; fi
if [[ ! ${#swp_proc_id[@]} -eq 0 ]]; then poblarMemoria; fi
if [[ ${#mem_proc_id[@]} -eq 0 ]]; then
if [[ ${#swp_proc_id[@]} -eq 0 ]] && [[ $tiempo -gt $tiempo_final ]]; then finalizarEjecucion 0; fi
if [[ ${proc_tamano[${swp_proc_index[0]}]} -gt $mem_tamano ]]; then finalizarEjecucion 20; fi
if [[ $tiempo -ge 0 ]]; then linea_tiempo[$tiempo]=-1; fi
else
calcularEjecucion
fi
if [[ -n $tiempo_break ]] && [[ $((tiempo + 1)) -eq $tiempo_break ]]; then
modo_debug=1
if [[ -n $modo_silencio ]]; then
modo_silencio_break=1
notacionCientifica $mem_tamano "mem_tamano_redondeado" "mem_tamano_abreviacion" #abrevia la memoria
notacionCientifica $mem_usada "mem_usada_redondeado" "mem_usada_abreviacion"
notacionCientifica $proc_count "proc_count_redondeado" "proc_count_abreviacion"
unset modo_silencio
fi
fi
if [[ -n $tiempo_unbreak ]] && [[ $tiempo -eq $tiempo_unbreak ]]; then
unset modo_debug
if [[ -n $modo_silencio_break ]]; then
modo_silencio=1
unset modo_silencio_break
fi
fi
if [[ -n $evento ]] || [[ -n $modo_debug ]]; then
salidaEjecucion
fi
if [[ -n $evento ]]; then
for ((i=0; i<${#evento_log[@]}; i++)); do
if [[ $(echo ${evento_log_NoEsc[$i]} | cut -d ' ' -f2) == 'termina' ]]; then
log 5 "$(echo ${evento_log[$i]} | cut -d '#' -f1)" "$(echo ${evento_log_NoEsc[$i]} | cut -d '#' -f1)"
evolucionPaginas $(echo ${evento_log_NoEsc[$i]} | cut -d '#' -f2)
else
log 5 "${evento_log[$i]}" "${evento_log_NoEsc[$i]}"
fi
done
pantalla "${evento::-2}"
evento_log=()
evento_log_NoEsc=()
fi
if [[ -n $evento ]] || [[ -n $modo_debug ]]; then
log 3
if [[ -z $modo_silencio ]]; then
read -p "Presiona cualquier tecla para continuar " -n 1 -r
fi
fi
unset evento
if [[ ${#mem_proc_id[@]} -gt 0 ]]; then
ejecucion
fi
((tiempo++))
}
#######################################
# Abrevia número
# Globales:
# Nada
# Argumentos:
# global abreviacion
# global redondeado
# numero
# Devuelve:
# Nada
#######################################
function notacionCientifica() {
local -ri numero=$1 #primer argumento es el numero a redondear
local -rn redondeado="$2" abreviacion="$3" #la variable donde se guardara la aproximación y la variable donde se guarda la abreviacion
local -i i=1000
while [[ -z $redondeado ]]; do
if [[ $numero -ge $i ]]; then
i=$((i * 1000))
else
case "$i" in
"1000")
abreviacion=;;
"1000000")
abreviacion="K";;
"1000000000")
abreviacion="M";;
"1000000000000")
abreviacion="G";;
"1000000000000000")
abreviacion="T";;
*)
abreviacion="?";;
esac
redondeado=$((numero % i / (i / 1000)))
fi
done
}
#######################################
# Mete procesos en swap
# Globales:
# evento
# evento_log
# evento_log_NoEsc
# proc_color
# proc_estado
# proc_id
# proc_tiempo_llegada
# swp_proc_id
# swp_proc_index
# tiempo
# Argumentos:
# Nada
# Devuelve:
# Nada
#######################################
function poblarSwap() {
local -i i
for (( i=0 ; i<${#proc_id[@]}; i++ )); do
if [[ ${proc_tiempo_llegada[$i]} -eq $tiempo ]]; then
evento+="\e[${proc_color[$i]}m${proc_id[$i]}\e[0m > \e[93mespera\e[0m, "
evento_log+=("\e[${proc_color[${i}]}m${proc_id[$i]}\e[0m entra en swap en instante \e[44m$tiempo")
evento_log_NoEsc+=("${proc_id[$i]} entra en swap en instante <${tiempo}>")
swp_proc_id+=("${proc_id[$i]}")
swp_proc_index+=("$i")
((proc_estado[i]|=2))
fi
done
}
#######################################
# Mete procesos en memoria
# Globales:
# evento
# evento_log
# evento_log_NoEsc
# mem_paginas
# mem_paginas_secuencia
# mem_proc_id
# mem_proc_index
# mem_proc_tamano
# mem_tamano
# mem_usada
# mem_usada_abreviacion
# mem_usada_redondeado
# modo_silencio
# proc_color
# proc_estado
# proc_tamano
# swp_proc_id
# swp_proc_index
# Argumentos:
# Nada
# Devuelve:
# Nada
#######################################
function poblarMemoria() {
local -i espacio_valido=1 i j index
local id
mem_usada=${#mem_paginas[@]} #memoria usada es igual al numero de paginas
if [[ -n $swp_proc_id ]]; then #si la swap no es nulo lo que pasara a continuacion te sorprendera...
until [[ ${proc_tamano[${swp_proc_index[0]}]} -gt $((mem_tamano - mem_usada)) ]] || [[ ${#swp_proc_id[@]} -eq 0 ]] || [[ $espacio_valido -eq 0 ]]; do #mientras el tamaño del primer proceso en el swap sea mayor que la memoria libre o el numero de procesos del swap sea cero hacer...
for ((i=0 ; i<=$((mem_tamano - proc_tamano[swp_proc_index[0]] )) ; i++ )); do #para i=0 hasta mayor que 500 menos el tamaño del primer proceso incrementar
espacio_valido=1 #define variable local espacio valido igual a 1
for ((j=0 ; j<proc_tamano[swp_proc_index[0]] ; j++ )); do #por cada tamaño del proceso
if [[ -z ${mem_paginas[$(($i + $j))]} ]]; then #si la memoria es nula
espacio_valido=$((espacio_valido * 1)) #entonces es valido
else
i=$((i + j)) #sino pasa al siguiente bloque de memoria
espacio_valido=0
break
fi
done
if [[ $espacio_valido -eq 1 ]]; then #si el espacio es valido entonces
index=${swp_proc_index[0]}
id=${swp_proc_id[0]}
evento+="\e[${proc_color[index]}m$id\e[0m > \e[92men memoria\e[0m, "
evento_log+=("\e[${proc_color[index]}m$id\e[0m entra en memoria en instante \e[44m$tiempo\e[0m, despues de esperar \e[44m$((tiempo - proc_tiempo_llegada[swp_proc_index[0]]))\e[0m")
evento_log_NoEsc+=("$id entra en memoria en instante <${tiempo}>, despues de esperar <$((tiempo - proc_tiempo_llegada[swp_proc_index[0]]))>")
mem_proc_id+=("$id") #guarda la id
mem_proc_index+=("$index") #guarda index
mem_proc_tamano+=("${proc_tamano[index]}") #guarda tamaño
((proc_estado[swp_proc_index[0]]|=4))
mem_usada=$((mem_usada + proc_tamano[swp_proc_index[0]])) #y actualiza la memoria usada
for ((j=0 ; j<proc_tamano[swp_proc_index[0]] ; j++ )); do #por cada tamaño del proceso
mem_paginas[$((i + j))]=$index #guarda la index de cada proceso de memoria en el espacio correspondiente
mem_paginas_secuencia[$((i + j))]=-1
done
actualizarPosiciones
unset swp_proc_id[0] #saca el proceso del swap
unset swp_proc_index[0]
swp_proc_id=("${swp_proc_id[@]}") #limpia espacios vacios de la lista
swp_proc_index=("${swp_proc_index[@]}")
break
fi
done
done
fi
if [[ -n $swp_proc_id ]] && [[ ${proc_tamano[${swp_proc_index[0]}]} -le $((mem_tamano - mem_usada)) ]]; then
desfragmentarMemoria
poblarMemoria
fi
if [[ -z $modo_silencio ]]; then
unset mem_usada_redondeado
notacionCientifica $mem_usada "mem_usada_redondeado" "mem_usada_abreviacion"
fi
}
#######################################
# Saca procesos de memoria
# Globales:
# evento
# evento_log
# evento_log_NoEsc
# mem_paginas
# mem_proc_id
# mem_proc_index
# mem_proc_tamano
# mem_tamano
# mem_usada
# mem_usada_abreviacion
# mem_usada_redondeado
# modo_silencio
# proc_color
# proc_estado
# proc_posicion
# proc_tiempo_ejecucion
# proc_tiempo_espera
# proc_tiempo_salida
# Argumentos:
# Indice de proceso
# Indice de memoria
# Devuelve:
# Nada
#######################################
function eliminarMemoria() {
local -ri index_objetivo=$1 index_mem_objetivo=$2
local -i i
for (( i=0 ; i<mem_tamano ; i++ )); do
if [[ -n ${mem_paginas[$i]} ]] && [[ ${mem_proc_index[$index_mem_objetivo]} -eq ${mem_paginas[$i]} ]]; then #si la id del proceso es igual a la id del que buscasa entonces...
unset mem_paginas[$i] #saca procesos de la memoria si
fi
done
i=0
for index in ${mem_proc_index[@]}; do #por cada indice en memoria hacer...
if [[ $index_objetivo -eq $index ]]; then #si lo encuentras entonces...
evento+="\e[${proc_color[${mem_proc_index[$i]}]}m${mem_proc_id[$i]}\e[0m > \e[96mfinaliza\e[0m, "
proc_tiempo_salida[$index]=$tiempo
((proc_estado[index]|=16))
evento_log+=("\e[${proc_color[${index}]}m${mem_proc_id[$i]}\e[0m termina en instante \e[44m$tiempo\e[0m, con tiempo de espera \e[44m${proc_tiempo_espera[$index]}\e[0m y tiempo de ejecución \e[44m${proc_tiempo_ejecucion[${index}]}#$index")
evento_log_NoEsc+=("${mem_proc_id[$i]} termina en instante <${tiempo}>, con tiempo de espera <${proc_tiempo_espera[$index]}> y tiempo de ejecución <${proc_tiempo_ejecucion[${index}]}>#$index")
unset mem_proc_index[$i] #saca el indice de memoria
unset mem_proc_id[$i] #saca el id de memoria
for pos in ${proc_posicion[$index]}; do #por cada posicion del proceso hacer...
unset mem_paginas_secuencia[$pos] #saca las paginas
done
unset proc_posicion[$index]
unset mem_proc_tamano[$i] #saca el proceso de tamaño de la memoria
mem_proc_index=( "${mem_proc_index[@]}" ) #desfragmenta la lista
mem_proc_id=( "${mem_proc_id[@]}" )
mem_proc_tamano=( "${mem_proc_tamano[@]}" )
fi
((i++))
done
if [[ -z $modo_silencio ]]; then
mem_usada=${#mem_paginas[@]}
unset mem_usada_redondeado
notacionCientifica $mem_usada "mem_usada_redondeado" "mem_usada_abreviacion"
fi
if [[ ! ${#swp_proc_id[@]} -eq 0 ]]; then poblarMemoria; fi
}
#######################################
# Agrupa procesos en memoria
# Globales:
# evento
# mem_paginas
# mem_paginas_secuencia
# mem_tamano
# mem_usada
# Argumentos:
# Nada
# Devuelve:
# Nada
#######################################
function desfragmentarMemoria() {
local -i i j
until [[ $((pivot_final + 1)) -eq $mem_usada ]]; do
local -i pivot=-1 pivot_final=0 count=0
for ((i=(mem_tamano - 1) ; i>=0 ; i-- )); do
if [[ -z ${mem_paginas[$i]} ]]; then
if [[ $pivot -gt 0 ]]; then ((count++)); fi
else
if [[ $pivot -lt 0 ]]; then pivot_final=$i; fi
pivot=$i
fi
done
if [[ ! $((pivot_final + 1)) -eq $mem_usada ]]; then
for ((j=0 ; j<=count ; j++ )); do # por cada hueco hace...
for ((i=0 ; i<=pivot_final ; i++ )); do #por cada proceso comprueba si hay un hueco a la izquierda
if [[ -z ${mem_paginas[$i]} ]] && [[ -n ${mem_paginas[$((i + 1))]} ]]; then #si hay hueco se mueve
mem_paginas[$i]=${mem_paginas[$((i + 1))]}