Пример #1
0
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);
}
Пример #2
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);
}
Пример #3
0
/**
 * 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);
}
Пример #4
0
/**
 * 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);
}
Пример #5
0
/**
 * 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);
}
Пример #6
0
/**
 * 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();
}
Пример #7
0
Synchronized::Synchronized(SEMAPHORE_ID semaphore)
{
	m_mutex = NULL;
	m_semaphore = semaphore;
	takeSemaphore(m_semaphore);
}