Merge branch 'main' into retrievedata

This commit is contained in:
Mylloon 2024-04-24 23:26:09 +02:00
commit f211870a18
Signed by: Anri
GPG key ID: A82D63DFF8D1317F
6 changed files with 344 additions and 339 deletions

View file

@ -32,7 +32,7 @@ release: compilation
debug: CFLAGS += -Wall -Wextra -Wshadow -Wcast-align -Wstrict-prototypes
debug: CFLAGS += -fanalyzer -fsanitize=undefined -g -Og
debug: LDFLAGS += -fsanitize=undefined -fsanitize=leak
debug: LDFLAGS += -fsanitize=undefined -fsanitize=thread
debug: compilation
compilation: $(ALL_OBJECTS)

16
README
View file

@ -10,11 +10,11 @@ Ce qui créer l'exécutable `ordonnanceur.elf`.
Paramètres disponibles :
- `-q` lance le benchmark avec quicksort
- `-m` lance le benchmark avec mandelbrot
- `-t n` où `n` est le nombre de threads à utiliser, 0 signifie qu'on utilise
* -q : lance le benchmark avec quicksort
* -m : lance le benchmark avec mandelbrot
* -t n : où `n` est le nombre de threads à utiliser, 0 signifie qu'on utilise
tous les cœurs disponibles.
- `-s` n'utilises pas d'ordonnanceur
* -s : n'utilises pas d'ordonnanceur
Exemple : quicksort en utilisant tous les cœurs disponibles
@ -27,10 +27,10 @@ Cible du makefile
Il est possible d'utiliser d'autres implémentations d'ordonnanceur en changeant
la cible du Makefile.
- `make threads` : lance juste des threads
- `make lifo` : utilisation d'une pile
- `make random` : idem que `lifo` mais en prenant une tâche aléatoire
- `make ws` : work-stealing
* `make threads` : lance juste des threads
* `make lifo` : utilisation d'une pile
* `make random` : idem que `lifo` mais en prenant une tâche aléatoire
* `make ws` : work-stealing
Infos

View file

@ -1,103 +1,103 @@
serial;solution1;solution2;solution3;solution4
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
3,699373;5,488023;0,47237;0,478026;0,433025
3,700028;5,455712;0,494962;0,43337;0,417979
3,706003;5,525636;0,454447;0,4357;0,433579
3,680465;5,782133;0,449261;0,448702;0,420426
3,755356;5,760779;0,430482;0,432999;0,421888
3,773443;5,628832;0,437057;0,451089;0,425781
3,762929;5,534626;0,451706;0,442623;0,434668
3,728524;5,547798;0,449807;0,435755;0,423926
3,765843;5,544817;0,437969;0,428514;0,416397
3,760712;5,559137;0,456097;0,459615;0,443395
;;0,435231;0,447139;0,417403
;;0,435863;0,431024;0,422645
;;0,47099;0,442824;0,438633
;;0,444217;0,426627;0,424975
;;0,441064;0,428842;0,426369
;;0,464321;0,455673;0,440124
;;0,440808;0,431802;0,421606
;;0,444501;0,431392;0,417215
;;0,466562;0,451748;0,438959
;;0,444408;0,440035;0,4254
;;0,440298;0,429963;0,418044
;;0,469805;0,445796;0,429213
;;0,435337;0,428611;0,429957
;;0,428776;0,430837;0,418727
;;0,439373;0,445644;0,428272
;;0,430075;0,439031;0,439621
;;0,448776;0,431147;0,414435
;;0,453934;0,452697;0,413957
;;0,436708;0,43642;0,438138
;;0,437682;0,439661;0,426635
;;0,458744;0,448007;0,422047
;;0,46211;0,439246;0,439724
;;0,439103;0,436682;0,420238
;;0,455765;0,443933;0,420346
;;0,435958;0,443765;0,441586
;;0,443098;0,43171;0,421882
;;0,46374;0,465626;0,420092
;;0,448221;0,434924;0,437275
;;0,45311;0,427708;0,421062
;;0,450469;0,427194;0,424122
;;0,430775;0,433748;0,422986
;;0,442299;0,420065;0,439952
;;0,449738;0,426692;0,495084
;;0,434351;0,437632;0,528238
;;0,42759;0,431623;0,525092
;;0,458849;0,42209;0,485978
;;0,441104;0,438151;0,464852
;;0,435596;0,422125;0,444847
;;0,451678;0,413834;0,452927
;;0,431298;0,449076;0,545694
;;0,434293;0,418434;0,472326
;;0,450405;0,425737;0,500946
;;0,429664;0,435361;0,507181
;;0,434408;0,428158;0,461463
;;0,44453;0,429692;0,46309
;;0,447389;0,428587;0,487651
;;0,44155;0,433786;0,50062
;;0,431118;0,423676;0,488046
;;0,448942;0,426093;0,471528
;;0,427483;0,44348;0,462296
;;0,429674;0,420654;0,456372
;;0,446553;0,422958;0,453673
;;0,426328;0,436407;0,428236
;;0,427325;0,422546;0,461682
;;0,450518;0,426066;0,437946
;;0,437274;0,439085;0,426752
;;0,430804;0,417064;0,449537
;;0,448709;0,422231;0,451591
;;0,436712;0,437314;0,461608
;;0,430153;0,426393;0,501439
;;0,444711;0,421434;0,471776
;;0,428339;0,430742;0,469594
;;0,422936;0,430833;0,449374
;;0,443323;0,419846;0,501901
;;0,424732;0,434814;0,470192
;;0,427097;0,442446;0,452176
;;0,444068;0,456833;0,439405
;;0,426348;0,438789;0,455701
;;0,421448;0,437946;0,528443
;;0,440158;0,430192;0,50939
;;0,442971;0,42516;0,482255
;;0,483969;0,456829;0,478885
;;0,427999;0,431844;0,465756
;;0,436225;0,435414;0,497307
;;0,423702;0,444849;0,523557
;;0,436075;0,420309;0,448597
;;0,438504;0,424081;0,515072
;;0,428824;0,439707;0,50559
;;0,435219;0,418414;0,442364
;;0,443414;0,425195;0,448883
;;0,435936;0,432847;0,429692
;;0,430754;0,426698;0,421615
;;0,440062;0,420274;0,435846
;;0,429719;0,440123;0,421792
;;0,427208;0,426243;0,425134
;;0,445394;0,419549;0,424762
;;0,422881;0,421731;0,428183
;;0,41912;0,433301;0,437734
;;0,431884;0,420508;0,422997
;;0,425924;0,423692;0,450753
;;;;
=AVERAGE(A2:A101);=AVERAGE(B2:B101);=AVERAGE(C2:C101);=AVERAGE(D2:D101);=AVERAGE(E2:E101)

1 serial solution1 solution2 solution3 solution4
2 3,699373 5,488023 0,47237 0,478026 0,433025
3 3,700028 5,455712 0,494962 0,43337 0,417979
4 3,706003 5,525636 0,454447 0,4357 0,433579
5 3,680465 5,782133 0,449261 0,448702 0,420426
6 3,755356 5,760779 0,430482 0,432999 0,421888
7 3,773443 5,628832 0,437057 0,451089 0,425781
8 3,762929 5,534626 0,451706 0,442623 0,434668
9 3,728524 5,547798 0,449807 0,435755 0,423926
10 3,765843 5,544817 0,437969 0,428514 0,416397
11 3,760712 5,559137 0,456097 0,459615 0,443395
12 0,435231 0,447139 0,417403
13 0,435863 0,431024 0,422645
14 0,47099 0,442824 0,438633
15 0,444217 0,426627 0,424975
16 0,441064 0,428842 0,426369
17 0,464321 0,455673 0,440124
18 0,440808 0,431802 0,421606
19 0,444501 0,431392 0,417215
20 0,466562 0,451748 0,438959
21 0,444408 0,440035 0,4254
22 0,440298 0,429963 0,418044
23 0,469805 0,445796 0,429213
24 0,435337 0,428611 0,429957
25 0,428776 0,430837 0,418727
26 0,439373 0,445644 0,428272
27 0,430075 0,439031 0,439621
28 0,448776 0,431147 0,414435
29 0,453934 0,452697 0,413957
30 0,436708 0,43642 0,438138
31 0,437682 0,439661 0,426635
32 0,458744 0,448007 0,422047
33 0,46211 0,439246 0,439724
34 0,439103 0,436682 0,420238
35 0,455765 0,443933 0,420346
36 0,435958 0,443765 0,441586
37 0,443098 0,43171 0,421882
38 0,46374 0,465626 0,420092
39 0,448221 0,434924 0,437275
40 0,45311 0,427708 0,421062
41 0,450469 0,427194 0,424122
42 0,430775 0,433748 0,422986
43 0,442299 0,420065 0,439952
44 0,449738 0,426692 0,495084
45 0,434351 0,437632 0,528238
46 0,42759 0,431623 0,525092
47 0,458849 0,42209 0,485978
48 0,441104 0,438151 0,464852
49 0,435596 0,422125 0,444847
50 0,451678 0,413834 0,452927
51 0,431298 0,449076 0,545694
52 0,434293 0,418434 0,472326
53 0,450405 0,425737 0,500946
54 0,429664 0,435361 0,507181
55 0,434408 0,428158 0,461463
56 0,44453 0,429692 0,46309
57 0,447389 0,428587 0,487651
58 0,44155 0,433786 0,50062
59 0,431118 0,423676 0,488046
60 0,448942 0,426093 0,471528
61 0,427483 0,44348 0,462296
62 0,429674 0,420654 0,456372
63 0,446553 0,422958 0,453673
64 0,426328 0,436407 0,428236
65 0,427325 0,422546 0,461682
66 0,450518 0,426066 0,437946
67 0,437274 0,439085 0,426752
68 0,430804 0,417064 0,449537
69 0,448709 0,422231 0,451591
70 0,436712 0,437314 0,461608
71 0,430153 0,426393 0,501439
72 0,444711 0,421434 0,471776
73 0,428339 0,430742 0,469594
74 0,422936 0,430833 0,449374
75 0,443323 0,419846 0,501901
76 0,424732 0,434814 0,470192
77 0,427097 0,442446 0,452176
78 0,444068 0,456833 0,439405
79 0,426348 0,438789 0,455701
80 0,421448 0,437946 0,528443
81 0,440158 0,430192 0,50939
82 0,442971 0,42516 0,482255
83 0,483969 0,456829 0,478885
84 0,427999 0,431844 0,465756
85 0,436225 0,435414 0,497307
86 0,423702 0,444849 0,523557
87 0,436075 0,420309 0,448597
88 0,438504 0,424081 0,515072
89 0,428824 0,439707 0,50559
90 0,435219 0,418414 0,442364
91 0,443414 0,425195 0,448883
92 0,435936 0,432847 0,429692
93 0,430754 0,426698 0,421615
94 0,440062 0,420274 0,435846
95 0,429719 0,440123 0,421792
96 0,427208 0,426243 0,425134
97 0,445394 0,419549 0,424762
98 0,422881 0,421731 0,428183
99 0,41912 0,433301 0,437734
100 0,431884 0,420508 0,422997
101 0,425924 0,423692 0,450753
102
103 =AVERAGE(A2:A101) =AVERAGE(B2:B101) =AVERAGE(C2:C101) =AVERAGE(D2:D101) =AVERAGE(E2:E101)

View file

@ -1,103 +1,103 @@
serial;solution1;solution2;solution3;solution4
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
;;;;
6,456785;7,686787;1,052787;1,035684;1,056697
5,961551;7,456977;1,090401;1,078624;1,070915
5,978221;7,492764;0,945853;0,940012;0,941003
5,987699;7,487839;0,961475;0,930909;0,947027
5,994593;7,475912;0,948906;0,93964;0,948985
5,978152;7,501028;0,96521;0,945842;0,960884
6,008653;7,492859;0,943485;0,938186;0,944773
5,931275;7,508583;0,947526;0,936625;0,958647
5,984718;7,48269;0,969535;0,941158;0,954904
5,926464;7,521487;1,095308;0,962646;0,952086
;;1,187541;1,120839;0,9507
;;1,180552;1,117982;1,011738
;;1,178994;1,101996;1,127789
;;1,198735;1,115272;1,118482
;;1,187537;1,114234;1,11758
;;1,169716;1,122988;1,129877
;;1,183357;1,116626;1,124217
;;1,201513;1,11083;1,114629
;;1,189228;1,112732;1,119815
;;1,185339;1,191832;1,111635
;;1,205089;1,1096;1,122624
;;1,190949;1,102573;1,116943
;;1,182796;1,104611;1,108262
;;1,182168;1,110547;1,112515
;;1,18521;1,120449;1,130948
;;1,186162;1,107524;1,10815
;;1,171052;1,104342;1,11375
;;1,174987;1,115831;1,063593
;;1,170191;1,115308;1,054527
;;1,183476;1,117734;1,067821
;;1,181003;1,098069;1,091237
;;1,176937;1,099926;1,063959
;;1,183003;1,104753;1,05376
;;1,164995;1,129294;1,068562
;;1,189621;1,103004;1,072569
;;1,189487;1,101624;1,05788
;;1,17728;1,107398;1,053151
;;1,176664;1,107917;1,054929
;;1,190181;1,106081;1,067136
;;1,171804;1,110127;1,056735
;;1,181075;1,103754;1,060074
;;1,171117;1,105473;1,048996
;;1,234976;1,111731;1,054774
;;1,19734;1,100651;1,063619
;;1,183142;1,106409;1,051499
;;1,184678;1,102033;1,051034
;;1,188219;1,111736;1,055196
;;1,169105;1,101426;1,056565
;;1,169737;1,102269;1,057922
;;1,182779;1,102808;1,052283
;;1,179676;1,103962;1,051546
;;1,192515;1,114528;1,054307
;;1,173776;1,104606;1,059195
;;1,18694;1,111368;1,065876
;;1,167176;1,10553;1,059063
;;1,184172;1,121461;1,055983
;;1,173655;1,101533;1,071379
;;1,174559;1,109685;1,059781
;;1,180622;1,105634;1,052543
;;1,186669;1,102102;1,052587
;;1,186964;1,110219;1,050079
;;1,180694;1,108002;1,055051
;;1,18293;1,112525;1,060719
;;1,185275;1,105263;1,053945
;;1,186219;1,114569;1,058368
;;1,186204;1,10186;1,044708
;;1,176664;1,103141;1,064363
;;1,188062;1,101297;1,058389
;;1,186302;1,107418;1,052813
;;1,174208;1,109082;1,057208
;;1,182153;1,103994;1,051057
;;1,169753;1,099634;1,069187
;;1,179525;1,10862;1,054363
;;1,176094;1,118282;1,049696
;;1,180424;1,109521;1,049554
;;1,174649;1,111231;1,059195
;;1,176279;1,109939;1,068946
;;1,185085;1,105018;1,055443
;;1,172958;1,119652;1,060145
;;1,179878;1,102493;1,0528
;;1,18904;1,103832;1,049931
;;1,185939;1,10617;1,068577
;;1,184071;1,110488;1,053296
;;1,176863;1,10142;1,053043
;;1,180537;1,10233;1,053079
;;1,175333;1,110237;1,064754
;;1,181432;1,102337;1,05552
;;1,176338;1,124259;1,053189
;;1,182357;1,160978;1,056288
;;1,188036;1,107052;1,056224
;;1,178734;1,107852;1,059644
;;1,248277;1,109694;1,060426
;;1,177892;1,106097;1,047429
;;1,192703;1,104682;1,052129
;;1,187199;1,105608;1,059152
;;1,190741;1,10163;1,062313
;;1,192773;1,110093;1,052282
;;1,17697;1,107769;1,055542
;;1,18526;1,109078;1,051843
;;1,177081;1,103607;1,056059
;;;;
=AVERAGE(A2:A101);=AVERAGE(B2:B101);=AVERAGE(C2:C101);=AVERAGE(D2:D101);=AVERAGE(E2:E101)

1 serial solution1 solution2 solution3 solution4
2 6,456785 7,686787 1,052787 1,035684 1,056697
3 5,961551 7,456977 1,090401 1,078624 1,070915
4 5,978221 7,492764 0,945853 0,940012 0,941003
5 5,987699 7,487839 0,961475 0,930909 0,947027
6 5,994593 7,475912 0,948906 0,93964 0,948985
7 5,978152 7,501028 0,96521 0,945842 0,960884
8 6,008653 7,492859 0,943485 0,938186 0,944773
9 5,931275 7,508583 0,947526 0,936625 0,958647
10 5,984718 7,48269 0,969535 0,941158 0,954904
11 5,926464 7,521487 1,095308 0,962646 0,952086
12 1,187541 1,120839 0,9507
13 1,180552 1,117982 1,011738
14 1,178994 1,101996 1,127789
15 1,198735 1,115272 1,118482
16 1,187537 1,114234 1,11758
17 1,169716 1,122988 1,129877
18 1,183357 1,116626 1,124217
19 1,201513 1,11083 1,114629
20 1,189228 1,112732 1,119815
21 1,185339 1,191832 1,111635
22 1,205089 1,1096 1,122624
23 1,190949 1,102573 1,116943
24 1,182796 1,104611 1,108262
25 1,182168 1,110547 1,112515
26 1,18521 1,120449 1,130948
27 1,186162 1,107524 1,10815
28 1,171052 1,104342 1,11375
29 1,174987 1,115831 1,063593
30 1,170191 1,115308 1,054527
31 1,183476 1,117734 1,067821
32 1,181003 1,098069 1,091237
33 1,176937 1,099926 1,063959
34 1,183003 1,104753 1,05376
35 1,164995 1,129294 1,068562
36 1,189621 1,103004 1,072569
37 1,189487 1,101624 1,05788
38 1,17728 1,107398 1,053151
39 1,176664 1,107917 1,054929
40 1,190181 1,106081 1,067136
41 1,171804 1,110127 1,056735
42 1,181075 1,103754 1,060074
43 1,171117 1,105473 1,048996
44 1,234976 1,111731 1,054774
45 1,19734 1,100651 1,063619
46 1,183142 1,106409 1,051499
47 1,184678 1,102033 1,051034
48 1,188219 1,111736 1,055196
49 1,169105 1,101426 1,056565
50 1,169737 1,102269 1,057922
51 1,182779 1,102808 1,052283
52 1,179676 1,103962 1,051546
53 1,192515 1,114528 1,054307
54 1,173776 1,104606 1,059195
55 1,18694 1,111368 1,065876
56 1,167176 1,10553 1,059063
57 1,184172 1,121461 1,055983
58 1,173655 1,101533 1,071379
59 1,174559 1,109685 1,059781
60 1,180622 1,105634 1,052543
61 1,186669 1,102102 1,052587
62 1,186964 1,110219 1,050079
63 1,180694 1,108002 1,055051
64 1,18293 1,112525 1,060719
65 1,185275 1,105263 1,053945
66 1,186219 1,114569 1,058368
67 1,186204 1,10186 1,044708
68 1,176664 1,103141 1,064363
69 1,188062 1,101297 1,058389
70 1,186302 1,107418 1,052813
71 1,174208 1,109082 1,057208
72 1,182153 1,103994 1,051057
73 1,169753 1,099634 1,069187
74 1,179525 1,10862 1,054363
75 1,176094 1,118282 1,049696
76 1,180424 1,109521 1,049554
77 1,174649 1,111231 1,059195
78 1,176279 1,109939 1,068946
79 1,185085 1,105018 1,055443
80 1,172958 1,119652 1,060145
81 1,179878 1,102493 1,0528
82 1,18904 1,103832 1,049931
83 1,185939 1,10617 1,068577
84 1,184071 1,110488 1,053296
85 1,176863 1,10142 1,053043
86 1,180537 1,10233 1,053079
87 1,175333 1,110237 1,064754
88 1,181432 1,102337 1,05552
89 1,176338 1,124259 1,053189
90 1,182357 1,160978 1,056288
91 1,188036 1,107052 1,056224
92 1,178734 1,107852 1,059644
93 1,248277 1,109694 1,060426
94 1,177892 1,106097 1,047429
95 1,192703 1,104682 1,052129
96 1,187199 1,105608 1,059152
97 1,190741 1,10163 1,062313
98 1,192773 1,110093 1,052282
99 1,17697 1,107769 1,055542
100 1,18526 1,109078 1,051843
101 1,177081 1,103607 1,056059
102
103 =AVERAGE(A2:A101) =AVERAGE(B2:B101) =AVERAGE(C2:C101) =AVERAGE(D2:D101) =AVERAGE(E2:E101)

View file

@ -10,7 +10,7 @@
#define WIDTH 3840
#define HEIGHT 2160
#define ITERATIONS 1000
#define CHUNK_SIZE 32
#define CHUNK_SIZE 8
#define SCALE (WIDTH / 4.0)
#define DX (WIDTH / 2)
@ -102,10 +102,10 @@ draw(void *closure, struct scheduler *s)
{
struct mandelbrot_args *args = (struct mandelbrot_args *)closure;
unsigned int *image = args->image;
unsigned int start_x = args->start_x;
unsigned int start_y = args->start_y;
unsigned int end_x = args->end_x;
unsigned int end_y = args->end_y;
int start_x = args->start_x;
int start_y = args->start_y;
int end_x = args->end_x;
int end_y = args->end_y;
free(closure);

View file

@ -4,21 +4,37 @@
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Tâche */
struct task_info {
void *closure;
taskfunc f;
};
struct scheduler {
/* Structure de chaque thread */
struct worker {
/* Premier élément du deque (dernier ajouter) */
int *bottom;
int bottom;
/* Variable de conditions pour reveillé les threads au besoin */
/* Mutex qui protège cette structure */
pthread_mutex_t mutex;
/* Deque de tâches */
struct task_info *tasks;
/* Thread */
pthread_t thread;
/* Dernier élément du deque (premier ajouter) */
int top;
};
/* Scheduler partagé */
struct scheduler {
/* Condition threads dormant */
pthread_cond_t cond;
/* Mutex qui protège les piles */
/* Mutex qui protège cette structure */
pthread_mutex_t mutex;
/* Nombre de threads instanciés */
@ -27,17 +43,11 @@ struct scheduler {
/* Compteur des threads dormants */
int nthsleep;
/* Taille des piles */
/* Taille deque */
int qlen;
/* Piles de tâches */
struct task_info **tasks;
/* Liste des threads */
pthread_t *threads;
/* Dernier élément du deque (premier ajouter) */
int *top;
/* Liste de workers par threads */
struct worker *workers;
};
/* Lance une tâche de la pile */
@ -46,18 +56,16 @@ void *sched_worker(void *);
/* Nettoie les opérations effectuées par l'initialisation de l'ordonnanceur */
int sched_init_cleanup(struct scheduler, int);
/* Récupère l'index du thread courant */
/* Récupère l'index du thread courant
*
* Assume que le mutex de l'ordonnanceur est verrouillé */
int current_thread(struct scheduler *);
int
sched_init(int nthreads, int qlen, taskfunc f, void *closure)
{
static struct scheduler sched;
sched.bottom = NULL;
sched.tasks = NULL;
sched.threads = NULL;
sched.top = NULL;
sched.workers = NULL;
if(qlen <= 0) {
fprintf(stderr, "qlen must be greater than 0\n");
@ -73,7 +81,11 @@ sched_init(int nthreads, int qlen, taskfunc f, void *closure)
}
sched.nthreads = 0;
sched.nthsleep = 0;
// Initialisation variable de condition
if(pthread_cond_init(&sched.cond, NULL) != 0) {
fprintf(stderr, "Can't init condition variable\n");
return sched_init_cleanup(sched, -1);
}
// Initialisation du mutex
if(pthread_mutex_init(&sched.mutex, NULL) != 0) {
@ -81,80 +93,73 @@ sched_init(int nthreads, int qlen, taskfunc f, void *closure)
return sched_init_cleanup(sched, -1);
}
// Initialisation variable de condition
if(pthread_cond_init(&sched.cond, NULL) != 0) {
fprintf(stderr, "Can't init varcond\n");
return sched_init_cleanup(sched, -1);
}
sched.nthsleep = 0;
// Initialisation du curseur suivant l'état de la pile de chaque processus
if(!(sched.bottom = malloc(nthreads * sizeof(int)))) {
perror("Cursor bottom stack");
return sched_init_cleanup(sched, -1);
}
if(!(sched.top = malloc(nthreads * sizeof(int)))) {
perror("Cursor top stack");
return sched_init_cleanup(sched, -1);
// Initialize workers
if(!(sched.workers = malloc(nthreads * sizeof(struct worker)))) {
perror("Workers");
return -1;
}
for(int i = 0; i < nthreads; ++i) {
sched.bottom[i] = 0;
sched.top[i] = 0;
sched.workers[i].bottom = 0;
sched.workers[i].top = 0;
// Initialisation mutex
if(pthread_mutex_init(&sched.workers[i].mutex, NULL) != 0) {
fprintf(stderr, "Can't init mutex %d\n", i);
return sched_init_cleanup(sched, -1);
}
// Allocation mémoire pour la pile de chaque processus
if(!(sched.tasks = malloc(nthreads * sizeof(struct task_info *)))) {
// Allocation mémoire deque
if(!(sched.workers[i].tasks =
malloc(sched.qlen * sizeof(struct task_info)))) {
fprintf(stderr, "Thread %d: ", i);
perror("Deque list");
return sched_init_cleanup(sched, -1);
}
for(int i = 0; i < nthreads; ++i) {
if(!(sched.tasks[i] = malloc(qlen * sizeof(struct task_info)))) {
fprintf(stderr, "Deque for thread %d: %s\n", i, strerror(errno));
return sched_init_cleanup(sched, -1);
}
}
// Initialise l'aléatoire
srand(time(NULL));
// Créer les threads
if(!(sched.threads = malloc(nthreads * sizeof(pthread_t)))) {
perror("Threads");
// Création des threads
for(int i = 0; i < nthreads; ++i) {
pthread_mutex_lock(&sched.mutex);
if(pthread_create(&sched.workers[i].thread, NULL, sched_worker,
(void *)&sched) != 0) {
fprintf(stderr, "Can't create thread %d\n", i);
// Annule les threads déjà créer
for(int j = 0; j < i; ++j) {
pthread_cancel(sched.workers[j].thread);
}
return sched_init_cleanup(sched, -1);
}
sched.nthreads++;
pthread_mutex_unlock(&sched.mutex);
}
// Ajoute la tâche initiale
if(sched_spawn(f, closure, &sched) < 0) {
fprintf(stderr, "Can't create the initial task\n");
fprintf(stderr, "Can't queue the initial task\n");
return sched_init_cleanup(sched, -1);
}
// Démarre les threads
// Attend la fin des threads
for(int i = 0; i < nthreads; ++i) {
if(pthread_create(&sched.threads[i], NULL, sched_worker, &sched) != 0) {
fprintf(stderr, "Can't create the thread %d\n", i);
if(i > 0) {
fprintf(stderr, ", cancelling already created threads...\n");
for(int j = 0; j < i; ++j) {
if(pthread_cancel(sched.threads[j]) != 0) {
fprintf(stderr, "Can't cancel the thread %d\n", j);
}
}
} else {
fprintf(stderr, "\n");
}
return sched_init_cleanup(sched, -1);
}
pthread_mutex_lock(&sched.mutex);
sched.nthreads++;
pthread_mutex_unlock(&sched.mutex);
}
for(int i = 0; i < nthreads; ++i) {
if((pthread_join(sched.threads[i], NULL) != 0)) {
if((pthread_join(sched.workers[i].thread, NULL) != 0)) {
fprintf(stderr, "Can't wait the thread %d\n", i);
// Quelque chose s'est mal passé, on annule les threads en cours
for(int j = 0; j < nthreads; ++j) {
if(j != i) {
pthread_cancel(sched.workers[j].thread);
}
}
return sched_init_cleanup(sched, -1);
}
}
@ -165,35 +170,20 @@ sched_init(int nthreads, int qlen, taskfunc f, void *closure)
int
sched_init_cleanup(struct scheduler s, int ret_code)
{
pthread_mutex_destroy(&s.mutex);
pthread_cond_destroy(&s.cond);
if(s.tasks) {
pthread_mutex_destroy(&s.mutex);
if(s.workers) {
for(int i = 0; i < s.nthreads; ++i) {
if(s.tasks[i]) {
free(s.tasks[i]);
s.tasks[i] = NULL;
}
pthread_mutex_destroy(&s.workers[i].mutex);
free(s.workers[i].tasks);
s.workers[i].tasks = NULL;
}
free(s.tasks);
s.tasks = NULL;
}
if(s.threads) {
free(s.threads);
s.threads = NULL;
}
if(s.bottom) {
free(s.bottom);
s.bottom = NULL;
}
if(s.top) {
free(s.top);
s.top = NULL;
free(s.workers);
s.workers = NULL;
}
return ret_code;
@ -204,14 +194,11 @@ current_thread(struct scheduler *s)
{
pthread_t current = pthread_self();
pthread_mutex_lock(&s->mutex);
for(int i = 0; i < s->nthreads; ++i) {
if(pthread_equal(s->threads[i], current)) {
pthread_mutex_unlock(&s->mutex);
if(pthread_equal(s->workers[i].thread, current)) {
return i;
}
}
pthread_mutex_unlock(&s->mutex);
return -1;
}
@ -220,24 +207,28 @@ int
sched_spawn(taskfunc f, void *closure, struct scheduler *s)
{
int th;
pthread_mutex_lock(&s->mutex);
if((th = current_thread(s)) < 0) {
th = 0;
}
pthread_mutex_lock(&s->mutex);
int next = (s->bottom[th] + 1) % s->qlen;
if(next == s->top[th]) {
pthread_mutex_unlock(&s->mutex);
pthread_mutex_lock(&s->workers[th].mutex);
int next = (s->workers[th].bottom + 1) % s->qlen;
if(next == s->workers[th].top) {
pthread_mutex_unlock(&s->workers[th].mutex);
fprintf(stderr, "Stack is full\n");
errno = EAGAIN;
return -1;
}
s->tasks[th][s->bottom[th]] = (struct task_info){closure, f};
s->bottom[th] = next;
s->workers[th].tasks[s->workers[th].bottom] =
(struct task_info){closure, f};
s->workers[th].bottom = next;
pthread_mutex_unlock(&s->mutex);
pthread_mutex_unlock(&s->workers[th].mutex);
return 0;
}
@ -249,55 +240,69 @@ sched_worker(void *arg)
// Récupère le processus courant (index tableau)
int curr_th;
pthread_mutex_lock(&s->mutex);
while((curr_th = current_thread(s)) < 0);
pthread_mutex_unlock(&s->mutex);
struct task_info task;
int found;
while(1) {
found = 0;
pthread_mutex_lock(&s->mutex);
pthread_mutex_lock(&s->workers[curr_th].mutex);
if(s->top[curr_th] != s->bottom[curr_th]) {
if(s->workers[curr_th].top != s->workers[curr_th].bottom) {
found = 1;
s->bottom[curr_th] = (s->bottom[curr_th] - 1 + s->qlen) % s->qlen;
task = s->tasks[curr_th][s->bottom[curr_th]];
s->workers[curr_th].bottom =
(s->workers[curr_th].bottom - 1 + s->qlen) % s->qlen;
task = s->workers[curr_th].tasks[s->workers[curr_th].bottom];
}
pthread_mutex_unlock(&s->workers[curr_th].mutex);
if(!found) {
// Vol car aucune tâche trouvée
for(int i = 0, k = rand() % (s->nthreads + 1), target;
i < s->nthreads; ++i) {
target = (i + k) % s->nthreads;
pthread_mutex_lock(&s->mutex);
int nthreads = s->nthreads;
pthread_mutex_unlock(&s->mutex);
if(s->top[target] != s->bottom[target]) {
for(int i = 0, k = rand() % (nthreads + 1), target; i < nthreads;
++i) {
target = (i + k) % nthreads;
pthread_mutex_lock(&s->workers[target].mutex);
if(s->workers[target].top != s->workers[target].bottom) {
// Tâche trouvée
found = 1;
s->bottom[target] =
(s->bottom[target] - 1 + s->qlen) % s->qlen;
task = s->tasks[target][s->bottom[target]];
s->workers[target].bottom =
(s->workers[target].bottom - 1 + s->qlen) % s->qlen;
task = s->workers[target].tasks[s->workers[target].bottom];
pthread_mutex_unlock(&s->workers[target].mutex);
break;
}
pthread_mutex_unlock(&s->workers[target].mutex);
}
// Aucune tâche à faire
if(!found) {
pthread_mutex_lock(&s->mutex);
s->nthsleep++;
// Ne partir que si tout le monde dort
if(s->nthsleep >= s->nthreads) {
pthread_cond_broadcast(&s->cond);
pthread_mutex_unlock(&s->mutex);
break;
}
pthread_cond_wait(&s->cond, &s->mutex);
s->nthsleep--;
pthread_mutex_unlock(&s->mutex);
continue;
}
}
pthread_cond_broadcast(&s->cond);
pthread_mutex_unlock(&s->mutex);
pthread_cond_signal(&s->cond);
// Exécute la tâche
task.f(task.closure, s);