void putBox(AssemblyLine *assemblyLine, Box box) { sleep(rand() % 2); int sent = 0; while (!sent) { if (assemblyLine->truckEnded == 1 && assemblyLine->currentWeight == 0) exit(0); takeSemaphore(START_LINE_SEMAPHORE); if (assemblyLine->maxWeight >= box.weight + assemblyLine->currentWeight && assemblyLine->currentBoxes + 1 <= assemblyLine->maxBoxes) { if(tryToTakeSemaphore(TRUCK_SEMAPHORE) == 1){ gettimeofday(&box.loadTime, NULL); assemblyLine->line[assemblyLine->currentBoxInLine++] = box; assemblyLine->currentBoxInLine %= MAX_BOXES_IN_ASSEMBLY_LINE; assemblyLine->currentWeight += box.weight; assemblyLine->currentBoxes++; sent = 1; releaseSemaphore(END_LINE_SEMAPHORE); } else { printf("TRUCK WILL BE FULL\n"); } } releaseSemaphore(START_LINE_SEMAPHORE); } printf("PLACED BOX: PID:%d | WEIGHT:%d | TIME:%ld | LEFT WEIGHT ON ASSEMBLY LINE:%d | LEFT BOXES:%d\n", box.workerID, box.weight, box.loadTime.tv_usec, assemblyLine->maxWeight - assemblyLine->currentWeight, assemblyLine->maxBoxes - assemblyLine->currentBoxes); if (assemblyLine->truckEnded == 1 && assemblyLine->currentWeight == 0) exit(0); }
/** * Initialize the Ultrasonic Sensor. * This is the common code that initializes the ultrasonic sensor given that there * are two digital I/O channels allocated. If the system was running in automatic mode (round robin) * when the new sensor is added, it is stopped, the sensor is added, then automatic mode is * restored. */ void Ultrasonic::Initialize() { m_table = NULL; bool originalMode = m_automaticEnabled; if (m_semaphore == 0) m_semaphore = initializeSemaphore(SEMAPHORE_FULL); SetAutomaticMode(false); // kill task when adding a new sensor takeSemaphore(m_semaphore); // link this instance on the list { m_nextSensor = m_firstSensor; m_firstSensor = this; } giveSemaphore(m_semaphore); m_counter = new Counter(m_echoChannel); // set up counter for this sensor m_counter->SetMaxPeriod(1.0); m_counter->SetSemiPeriodMode(true); m_counter->Reset(); m_enabled = true; // make it available for round robin scheduling SetAutomaticMode(originalMode); static int instances = 0; instances++; HALReport(HALUsageReporting::kResourceType_Ultrasonic, instances); LiveWindow::GetInstance()->AddSensor("Ultrasonic", m_echoChannel->GetChannel(), this); }
/** * Free the resources for a timer event. * All resources will be freed and the timer event will be removed from the * queue if necessary. */ Notifier::~Notifier() { { Synchronized sync(queueSemaphore); DeleteFromQueue(); // Delete the static variables when the last one is going away if (!(--refcount)) { task->Stop(); delete task; } } // Acquire the semaphore; this makes certain that the handler is // not being executed by the interrupt manager. takeSemaphore(m_handlerSemaphore); // Delete while holding the semaphore so there can be no race. deleteSemaphore(m_handlerSemaphore); }
/** * Free the resources for a timer event. * All resources will be freed and the timer event will be removed from the * queue if necessary. */ Notifier::~Notifier() { { ::std::unique_lock<ReentrantMutex> sync(queueSemaphore); DeleteFromQueue(); // Delete the static variables when the last one is going away if (!(--refcount)) { int32_t status = 0; cleanNotifier(m_notifier, &status); wpi_setErrorWithContext(status, getHALErrorMessage(status)); } } // Acquire the semaphore; this makes certain that the handler is // not being executed by the interrupt manager. takeSemaphore(m_handlerSemaphore); // Delete while holding the semaphore so there can be no race. deleteSemaphore(m_handlerSemaphore); }
/** * Destructor for the ultrasonic sensor. * Delete the instance of the ultrasonic sensor by freeing the allocated digital channels. * If the system was in automatic mode (round robin), then it is stopped, then started again * after this sensor is removed (provided this wasn't the last sensor). */ Ultrasonic::~Ultrasonic() { bool wasAutomaticMode = m_automaticEnabled; SetAutomaticMode(false); if (m_allocatedChannels) { delete m_pingChannel; delete m_echoChannel; } wpi_assert(m_firstSensor != NULL); takeSemaphore(m_semaphore); { if (this == m_firstSensor) { m_firstSensor = m_nextSensor; if (m_firstSensor == NULL) { SetAutomaticMode(false); } } else { wpi_assert(m_firstSensor->m_nextSensor != NULL); for (Ultrasonic *s = m_firstSensor; s != NULL; s = s->m_nextSensor) { if (this == s->m_nextSensor) { s->m_nextSensor = s->m_nextSensor->m_nextSensor; break; } } } } giveSemaphore(m_semaphore); if (m_firstSensor != NULL && wasAutomaticMode) SetAutomaticMode(true); }
/** * ProcessQueue is called whenever there is a timer interrupt. * We need to wake up and process the current top item in the timer queue as long * as its scheduled time is after the current time. Then the item is removed or * rescheduled (repetitive events) in the queue. */ void Notifier::ProcessQueue(uint32_t mask, void *params) { Notifier *current; while (true) // keep processing past events until no more { { Synchronized sync(queueSemaphore); double currentTime = GetClock(); current = timerQueueHead; if (current == NULL || current->m_expirationTime > currentTime) { break; // no more timer events to process } // need to process this entry timerQueueHead = current->m_nextEvent; if (current->m_periodic) { // if periodic, requeue the event // compute when to put into queue current->InsertInQueue(true); } else { // not periodic; removed from queue current->m_queued = false; } // Take handler semaphore while holding queue semaphore to make sure // the handler will execute to completion in case we are being deleted. takeSemaphore(current->m_handlerSemaphore); } current->m_handler(current->m_param); // call the event handler giveSemaphore(current->m_handlerSemaphore); } // reschedule the first item in the queue Synchronized sync(queueSemaphore); UpdateAlarm(); }
Synchronized::Synchronized(SEMAPHORE_ID semaphore) { m_mutex = NULL; m_semaphore = semaphore; takeSemaphore(m_semaphore); }