--- joko/Uni/BSArch/02/bakery.c 2006/05/26 11:08:12 1.2 +++ joko/Uni/BSArch/02/bakery.c 2006/05/28 02:40:05 1.4 @@ -2,6 +2,18 @@ #include #include "bakery.h" +/* Hilfsfunktion, um höchsten Wert (integer) in einem Array zu bestimmen */ +int maxValueInList(int list[], int list_length) { + int i; + int max_value = 0; + for (i = 0; i < list_length; i++) { + if (list[i] > max_value) + max_value = list[i]; + } + return max_value; +} + +/* Initialisiert Struktur zur Verwaltung kritischer Abschnitte */ void My_InitializeCriticalSection( MY_LPCRITICAL_SECTION * sec ) { int i; @@ -9,7 +21,7 @@ /* Datenstruktur "erzeugen" */ *sec = malloc(sizeof(struct _crit_sec)); - /* Datenstruktur mit "0" initialisieren */ + /* Felder der Datenstruktur mit "0" initialisieren */ for (i = 0; i < MAX_THREADS; i++) { (*sec)->choosing[i] = 0; (*sec)->number[i] = 0; @@ -17,9 +29,50 @@ } +/* Gibt Speicher zur Verwaltung kritischer Abschnitte wieder frei */ void My_DeleteCriticalSection( MY_LPCRITICAL_SECTION sec ) { /* Datenstruktur freigeben */ free(sec); } + +/* Eintritt in kritischen Abschnitt */ +void My_EnterCriticalSection( int ThId, MY_LPCRITICAL_SECTION sec ) { + + int j; + + /* Beginn der Ticket-ID Berechnung */ + sec->choosing[ThId] = 1; + + /* Neue Ticket-ID berechnen und zuweisen */ + sec->number[ThId] = maxValueInList(sec->number, MAX_THREADS) + 1; + + /* Ende der Ticket-ID Berechnung */ + sec->choosing[ThId] = 0; + + /* Alle Threads durchlaufen */ + for (j = 0; j < MAX_THREADS; j++) { + + /* Warten, falls ein anderer Thread momentan eine Ticket-ID berechnet (busy wait) */ + while (sec->choosing[j] == 1); + + /* Bakery Algorithmus: Warten, bis man an der Reihe ist (busy wait) */ + while ( (sec->number[j] != 0) && + ( + (sec->number[j] < sec->number[ThId]) || + ((sec->number[j] == sec->number[ThId]) && j < ThId) + ) + ); + + } + +} + +/* Austritt aus kritischem Abschnitt */ +void My_LeaveCriticalSection( int ThId, MY_LPCRITICAL_SECTION sec ) { + + /* Ticket löschen */ + sec->number[ThId] = 0; + +}