|
@@ -21,12 +21,8 @@
|
|
|
/*
|
|
|
* replace this with declarations of any synchronization and other variables you need here
|
|
|
*/
|
|
|
-static struct semaphore * intersectionSem;
|
|
|
static struct lock * globlock;
|
|
|
-static struct semaphore * nsem;
|
|
|
-static struct semaphore * esem;
|
|
|
-static struct semaphore * ssem;
|
|
|
-static struct semaphore * ssem;
|
|
|
+typedef struct cv cv;
|
|
|
|
|
|
// This section contains global vars and useful functions to work with them. As well as the structs used for them
|
|
|
typedef struct car
|
|
@@ -35,6 +31,7 @@ typedef struct car
|
|
|
Direction dest;
|
|
|
bool old;
|
|
|
car * next;
|
|
|
+ cv * cv;
|
|
|
} car;
|
|
|
|
|
|
typedef struct list
|
|
@@ -61,6 +58,7 @@ car * newcar(Direction origin, Direction dest)
|
|
|
temp->dest = dest;
|
|
|
temp->old = 0;
|
|
|
temp->next = NULL;
|
|
|
+ temp->cv = NULL;
|
|
|
}
|
|
|
|
|
|
// list initializer/allocator
|
|
@@ -152,6 +150,13 @@ void clearint(car * done)
|
|
|
|
|
|
temp2->next = temp->next;
|
|
|
SKIP1:
|
|
|
+
|
|
|
+ if (temp->cv) // if this car was blocking something
|
|
|
+ {
|
|
|
+ cv_broadcast(temp->cv, globlock); // wake all/inform them you're all good
|
|
|
+ kfree(temp->cv);
|
|
|
+ }
|
|
|
+
|
|
|
kfree(temp);
|
|
|
}
|
|
|
|
|
@@ -163,11 +168,12 @@ void dellist(list * dead)
|
|
|
while (temp)
|
|
|
{
|
|
|
car * temp2 = temp->next;
|
|
|
+ kfree(temp->cv);
|
|
|
kfree(temp);
|
|
|
temp = temp2;
|
|
|
}
|
|
|
|
|
|
- kree(dead);
|
|
|
+ kfree(dead);
|
|
|
}
|
|
|
|
|
|
// returns true if a car is turning right
|
|
@@ -185,44 +191,18 @@ bool rightturn(car * car)
|
|
|
*
|
|
|
*/
|
|
|
void
|
|
|
-intersection_sync_init(void)
|
|
|
+intersection_sync_init()
|
|
|
{
|
|
|
- /* replace this default implementation with your own implementation */
|
|
|
-
|
|
|
- intersectionSem = sem_create("intersectionSem",1);
|
|
|
- if (intersectionSem == NULL)
|
|
|
- {
|
|
|
- panic("could not create intersection semaphore");
|
|
|
- }
|
|
|
- return;
|
|
|
-
|
|
|
- nsem = sem_create("nsem",1);
|
|
|
- if (intersectionSem == NULL)
|
|
|
- {
|
|
|
- panic("could not create intersection semaphore");
|
|
|
- }
|
|
|
- return;
|
|
|
-
|
|
|
- intersectionSem = sem_create("intersectionSem",1);
|
|
|
- if (intersectionSem == NULL)
|
|
|
- {
|
|
|
- panic("could not create intersection semaphore");
|
|
|
- }
|
|
|
- return;
|
|
|
+ globlock = lock_create("lightlock");
|
|
|
|
|
|
- intersectionSem = sem_create("intersectionSem",1);
|
|
|
- if (intersectionSem == NULL)
|
|
|
+ if (!(globlock))
|
|
|
{
|
|
|
- panic("could not create intersection semaphore");
|
|
|
+ kprintf("Failed to create lock!");
|
|
|
+ panic();
|
|
|
}
|
|
|
- return;
|
|
|
|
|
|
- intersectionSem = sem_create("intersectionSem",1);
|
|
|
- if (intersectionSem == NULL)
|
|
|
- {
|
|
|
- panic("could not create intersection semaphore");
|
|
|
- }
|
|
|
- return;
|
|
|
+ queue = newlist();
|
|
|
+ active = newlist();
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -234,13 +214,12 @@ intersection_sync_init(void)
|
|
|
*/
|
|
|
void intersection_sync_cleanup()
|
|
|
{
|
|
|
- KASSERT(intersectionSem);
|
|
|
KASSERT(queue);
|
|
|
KASSERT(active);
|
|
|
|
|
|
- sem_destroy(intersectionSem);
|
|
|
dellist(queue);
|
|
|
dellist(active);
|
|
|
+ lock_destroy(globlock);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -259,25 +238,19 @@ void intersection_sync_cleanup()
|
|
|
|
|
|
void intersection_before_entry(Direction origin, Direction destination)
|
|
|
{
|
|
|
- /* replace this default implementation with your own implementation */
|
|
|
- (void)origin; /* avoid compiler complaint about unused parameter */
|
|
|
- (void)destination; /* avoid compiler complaint about unused parameter */
|
|
|
- KASSERT(intersectionSem);
|
|
|
- P(intersectionSem);
|
|
|
-
|
|
|
- // starting my own shit
|
|
|
-
|
|
|
+ lock_acquire(globlock);
|
|
|
car * new = newcar(origin, destination);
|
|
|
|
|
|
+ RESTART:
|
|
|
+
|
|
|
// Nothing in intersection, so proceed
|
|
|
if (!(active->front))
|
|
|
{
|
|
|
push(new);
|
|
|
+ lock_release(globlock);
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
- // things are in the intersection
|
|
|
- if (active->front)
|
|
|
+ else // things are in the intersection
|
|
|
{
|
|
|
car * temp = active->front;
|
|
|
|
|
@@ -292,11 +265,21 @@ void intersection_before_entry(Direction origin, Direction destination)
|
|
|
{
|
|
|
enqueue(new);
|
|
|
new->old = 1; // make new "old", since now it has already waited once
|
|
|
- // SLEEP AND SET TO WAKE ONCE temp is out of the intersection!
|
|
|
+ lock_release(globlock);
|
|
|
+
|
|
|
+ // create cv for temp if it doesn't have one yet
|
|
|
+ if(!(temp->cv))
|
|
|
+ {
|
|
|
+ temp->cv = cv_create("carcv");
|
|
|
+ }
|
|
|
+
|
|
|
+ cv_wait(temp->cv, globlock); // sleep and reacquire lock once woken
|
|
|
+ goto RESTART; // now we have to make sure there's nothing else screwing us over
|
|
|
}
|
|
|
}
|
|
|
|
|
|
push(new);
|
|
|
+ lock_release(globlock);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -314,21 +297,13 @@ void intersection_before_entry(Direction origin, Direction destination)
|
|
|
|
|
|
void intersection_after_exit(Direction origin, Direction destination)
|
|
|
{
|
|
|
- /* replace this default implementation with your own implementation */
|
|
|
- (void)origin; /* avoid compiler complaint about unused parameter */
|
|
|
- (void)destination; /* avoid compiler complaint about unused parameter */
|
|
|
- KASSERT(intersectionSem);
|
|
|
- V(intersectionSem);
|
|
|
-
|
|
|
- // My shit
|
|
|
-
|
|
|
car * temp = active->first;
|
|
|
|
|
|
while (temp)
|
|
|
{
|
|
|
if (temp->origin == origin && temp->dest == destination)
|
|
|
{
|
|
|
- clearing(temp);
|
|
|
+ clearint(temp);
|
|
|
break;
|
|
|
}
|
|
|
else
|