Merge branch 'main' into retrievedata
This commit is contained in:
commit
f211870a18
6 changed files with 344 additions and 339 deletions
2
Makefile
2
Makefile
|
@ -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)
|
||||
|
|
18
README
18
README
|
@ -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
|
||||
tous les cœurs disponibles.
|
||||
- `-s` n'utilises pas d'ordonnanceur
|
||||
* -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
|
||||
|
||||
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
|
||||
|
|
|
@ -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,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)
|
||||
|
|
|
|
@ -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);
|
||||
|
||||
|
|
247
src/sched-ws.c
247
src/sched-ws.c
|
@ -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,34 +93,28 @@ 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;
|
||||
|
||||
// Allocation mémoire pour la pile de chaque processus
|
||||
if(!(sched.tasks = malloc(nthreads * sizeof(struct task_info *)))) {
|
||||
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));
|
||||
// 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 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);
|
||||
}
|
||||
}
|
||||
|
@ -116,45 +122,44 @@ sched_init(int nthreads, int qlen, taskfunc f, void *closure)
|
|||
// Initialise l'aléatoire
|
||||
srand(time(NULL));
|
||||
|
||||
// Créer les threads
|
||||
if(!(sched.threads = malloc(nthreads * sizeof(pthread_t)))) {
|
||||
perror("Threads");
|
||||
return sched_init_cleanup(sched, -1);
|
||||
}
|
||||
|
||||
// Ajoute la tâche initiale
|
||||
if(sched_spawn(f, closure, &sched) < 0) {
|
||||
fprintf(stderr, "Can't create the initial task\n");
|
||||
return sched_init_cleanup(sched, -1);
|
||||
}
|
||||
|
||||
// Démarre les threads
|
||||
// Création 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);
|
||||
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);
|
||||
|
||||
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");
|
||||
// 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);
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&sched.mutex);
|
||||
sched.nthreads++;
|
||||
|
||||
pthread_mutex_unlock(&sched.mutex);
|
||||
}
|
||||
|
||||
// Ajoute la tâche initiale
|
||||
if(sched_spawn(f, closure, &sched) < 0) {
|
||||
fprintf(stderr, "Can't queue the initial task\n");
|
||||
return sched_init_cleanup(sched, -1);
|
||||
}
|
||||
|
||||
// Attend la fin des threads
|
||||
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_unlock(&s->mutex);
|
||||
|
||||
pthread_mutex_lock(&s->mutex);
|
||||
pthread_mutex_lock(&s->workers[th].mutex);
|
||||
|
||||
int next = (s->bottom[th] + 1) % s->qlen;
|
||||
if(next == s->top[th]) {
|
||||
pthread_mutex_unlock(&s->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);
|
||||
|
|
Reference in a new issue