1 |
|
|
2 |
|
#include <stdlib.h> |
3 |
|
#include "bakery.h" |
4 |
|
|
5 |
|
/* Hilfsfunktion, um höchsten Wert (integer) in einem Array zu bestimmen */ |
6 |
|
int maxValueInList(int list[], int list_length) { |
7 |
|
int i; |
8 |
|
int max_value = 0; |
9 |
|
for (i = 0; i < list_length; i++) { |
10 |
|
if (list[i] > max_value) |
11 |
|
max_value = list[i]; |
12 |
|
} |
13 |
|
return max_value; |
14 |
|
} |
15 |
|
|
16 |
|
/* Initialisiert Struktur zur Verwaltung kritischer Abschnitte */ |
17 |
|
void My_InitializeCriticalSection( MY_LPCRITICAL_SECTION * sec ) { |
18 |
|
|
19 |
|
int i; |
20 |
|
|
21 |
|
/* Datenstruktur "erzeugen" */ |
22 |
|
*sec = malloc(sizeof(struct _crit_sec)); |
23 |
|
|
24 |
|
/* Felder der Datenstruktur mit "0" initialisieren */ |
25 |
|
for (i = 0; i < MAX_THREADS; i++) { |
26 |
|
(*sec)->choosing[i] = 0; |
27 |
|
(*sec)->number[i] = 0; |
28 |
|
} |
29 |
|
|
30 |
|
} |
31 |
|
|
32 |
|
/* Gibt Speicher zur Verwaltung kritischer Abschnitte wieder frei */ |
33 |
|
void My_DeleteCriticalSection( MY_LPCRITICAL_SECTION sec ) { |
34 |
|
|
35 |
|
/* Datenstruktur freigeben */ |
36 |
|
free(sec); |
37 |
|
|
38 |
|
} |
39 |
|
|
40 |
|
/* Eintritt in kritischen Abschnitt */ |
41 |
|
void My_EnterCriticalSection( int ThId, MY_LPCRITICAL_SECTION sec ) { |
42 |
|
|
43 |
|
int j; |
44 |
|
|
45 |
|
/* Beginn der Ticket-ID Berechnung */ |
46 |
|
sec->choosing[ThId] = 1; |
47 |
|
|
48 |
|
/* Neue Ticket-ID berechnen und zuweisen */ |
49 |
|
sec->number[ThId] = maxValueInList(sec->number, MAX_THREADS) + 1; |
50 |
|
|
51 |
|
/* Ende der Ticket-ID Berechnung */ |
52 |
|
sec->choosing[ThId] = 0; |
53 |
|
|
54 |
|
/* Alle Threads durchlaufen */ |
55 |
|
for (j = 0; j < MAX_THREADS; j++) { |
56 |
|
|
57 |
|
/* Warten, falls ein anderer Thread momentan eine Ticket-ID berechnet (busy wait) */ |
58 |
|
while (sec->choosing[j] == 1); |
59 |
|
|
60 |
|
/* Bakery Algorithmus: Warten, bis man an der Reihe ist (busy wait) */ |
61 |
|
while ( (sec->number[j] != 0) && |
62 |
|
( |
63 |
|
(sec->number[j] < sec->number[ThId]) || |
64 |
|
((sec->number[j] == sec->number[ThId]) && j < ThId) |
65 |
|
) |
66 |
|
); |
67 |
|
|
68 |
|
} |
69 |
|
|
70 |
|
} |
71 |
|
|
72 |
|
/* Austritt aus kritischem Abschnitt */ |
73 |
|
void My_LeaveCriticalSection( int ThId, MY_LPCRITICAL_SECTION sec ) { |
74 |
|
|
75 |
|
/* Ticket löschen */ |
76 |
|
sec->number[ThId] = 0; |
77 |
|
|
78 |
|
} |