Exemple #1
0
void *core_processing_thread_func(void *priv) {

	struct core_processing_thread *tpriv = priv;

	if (packet_info_pool_init()) {
		halt("Error while initializing the packet_info_pool", 1);
		return NULL;
	}

	registry_perf_inc(perf_thread_active, 1);

	pom_mutex_lock(&tpriv->pkt_queue_lock);

	while (core_run) {
		
		while (!tpriv->pkt_queue_head) {
			// We are not active while waiting for a packet
			registry_perf_dec(perf_thread_active, 1);

			debug_core("thread %u : waiting", tpriv->thread_id);

			if (registry_perf_getval(perf_thread_active) == 0) {
				if (core_get_state() == core_state_finishing)
					core_set_state(core_state_idle);
			}

			if (!core_run) {
				pom_mutex_unlock(&tpriv->pkt_queue_lock);
				goto end;
			}

			int res = pthread_cond_wait(&tpriv->pkt_queue_cond, &tpriv->pkt_queue_lock);
			if (res) {
				pomlog(POMLOG_ERR "Error while waiting for restart condition : %s", pom_strerror(res));
				abort();
				return NULL;
			}
			registry_perf_inc(perf_thread_active, 1);
		}


		// Dequeue a packet
		struct core_packet_queue *tmp = tpriv->pkt_queue_head;
		tpriv->pkt_queue_head = tmp->next;
		if (!tpriv->pkt_queue_head)
			tpriv->pkt_queue_tail = NULL;


		// Add it to the unused list
		tmp->next = tpriv->pkt_queue_unused;
		tpriv->pkt_queue_unused = tmp;

		tpriv->pkt_count--;

		registry_perf_dec(perf_pkt_queue, 1);

		__sync_fetch_and_sub(&core_pkt_queue_count, 1);

		if (tpriv->pkt_count < CORE_THREAD_PKT_QUEUE_MIN) {

			pom_mutex_lock(&core_pkt_queue_wait_lock);
			// Tell the input processes that they can continue queuing packets
			int res = pthread_cond_broadcast(&core_pkt_queue_wait_cond);
			if (res) {
				pomlog(POMLOG_ERR "Error while signaling the main pkt_queue condition : %s", pom_strerror(res));
				abort();
			}
			pom_mutex_unlock(&core_pkt_queue_wait_lock);
		}

		// Keep track of our packet
		struct packet *pkt = tmp->pkt;

		debug_core("thread %u : Processing packet %p (%u.%06u)", tpriv->thread_id, pkt, pom_ptime_sec(pkt->ts), pom_ptime_usec(pkt->ts));
		pom_mutex_unlock(&tpriv->pkt_queue_lock);

		// Lock the processing lock
		pom_rwlock_rlock(&core_processing_lock);

		// Update the current clock
		if (core_clock[tpriv->thread_id] < pkt->ts) // Make sure we keep it monotonous
			core_clock[tpriv->thread_id] = pkt->ts;

		//pomlog(POMLOG_DEBUG "Thread %u processing ...", pthread_self());
		if (core_process_packet(pkt) == POM_ERR) {
			core_run = 0;
			pom_rwlock_unlock(&core_processing_lock);
			break;
		}

		// Process timers
		if (timers_process() != POM_OK) {
			pom_rwlock_unlock(&core_processing_lock);
			break;
		}

		pom_rwlock_unlock(&core_processing_lock);

		if (packet_release(pkt) != POM_OK) {
			pomlog(POMLOG_ERR "Error while releasing the packet");
			break;
		}
		
		debug_core("thread %u : Processed packet %p (%u.%06u)", tpriv->thread_id, pkt, pom_ptime_sec(pkt->ts), pom_ptime_usec(pkt->ts));
		// Re-lock our queue for the next run
		pom_mutex_lock(&tpriv->pkt_queue_lock);

	}

	halt("Processing thread encountered an error", 1);
end:
	packet_info_pool_cleanup();

	return NULL;
}
Exemple #2
0
void *core_processing_thread_func(void *priv) {

	struct core_processing_thread *tpriv = priv;

	pom_mutex_lock(&core_pkt_queue_mutex);

	while (core_run) {
		
		while (!core_pkt_queue_head && !tpriv->pkt_queue_head) {
			if (core_thread_active == 0) {
				if (core_get_state() == core_state_finishing)
					core_set_state(core_state_idle);
			}

			if (!core_run) {
				pom_mutex_unlock(&core_pkt_queue_mutex);
				return NULL;
			}

			if (pthread_cond_wait(&core_pkt_queue_restart_cond, &core_pkt_queue_mutex)) {
				pomlog(POMLOG_ERR "Error while waiting for restart condition : %s", pom_strerror(errno));
				// Should probably abort here
				return NULL;
			}

		}
		core_thread_active++;

		struct core_packet_queue *tmp = NULL;
		
		// Dequeue packets from our own queue first
		struct packet *pkt = NULL;
		if (tpriv->pkt_queue_head) {
			tmp = tpriv->pkt_queue_head;
			pkt = tmp->pkt;

			tpriv->pkt_queue_head = tmp->next;
			if (tpriv->pkt_queue_head)
				tpriv->pkt_queue_head->prev = NULL;
			else
				tpriv->pkt_queue_tail = NULL;

		} else {
			tmp = core_pkt_queue_head;
			pkt = tmp->pkt;

			// Remove the packet from the main queue
			core_pkt_queue_head = tmp->next;
			if (core_pkt_queue_head)
				core_pkt_queue_head->prev = NULL;
			else
				core_pkt_queue_tail = NULL;
		}

		// Add it to the unused list
		memset(tmp, 0, sizeof(struct core_packet_queue));
		tmp->next = core_pkt_queue_unused;
		if (tmp->next)
			tmp->next->prev = tmp;
		core_pkt_queue_unused = tmp;

		core_pkt_queue_usage--;

		pom_mutex_unlock(&core_pkt_queue_mutex);

		// Lock the processing thread
		if (pthread_rwlock_rdlock(&core_processing_lock)) {
			pomlog(POMLOG_ERR "Error while locking the processing lock : %s", pom_strerror(errno));
			abort();
			return NULL;
		}

		// Update the current clock
		pom_mutex_lock(&core_clock_lock);
		memcpy(&core_clock, &pkt->ts, sizeof(struct timeval));
		pom_mutex_unlock(&core_clock_lock);

		//pomlog(POMLOG_DEBUG "Thread %u processing ...", pthread_self());
		if (core_process_packet(pkt) == POM_ERR) {
			core_run = 0;
			halt("Packet processing encountered an error", 1);
			pthread_cond_broadcast(&core_pkt_queue_restart_cond);
			pthread_rwlock_unlock(&core_processing_lock);
			return NULL;
		}

		// Process timers
		if (timers_process() != POM_OK) {
			pthread_rwlock_unlock(&core_processing_lock);
			return NULL;
		}

		if (pthread_rwlock_unlock(&core_processing_lock)) {
			pomlog(POMLOG_ERR "Error while releasing the processing lock : %s", pom_strerror(errno));
			break;
		}

		if (packet_pool_release(pkt) != POM_OK) {
			pomlog(POMLOG_ERR "Error while releasing the packet to the pool");
			break;
		}
		
		pom_mutex_lock(&core_pkt_queue_mutex);
		if (pthread_cond_broadcast(&core_pkt_queue_restart_cond)) {
			pomlog(POMLOG_ERR "Error while signaling the done condition : %s", pom_strerror(errno));
			pom_mutex_unlock(&core_pkt_queue_mutex);
			break;

		}
		core_thread_active--;

	}
	pom_mutex_unlock(&core_pkt_queue_mutex);

	halt("Processing thread encountered an error", 1);
	return NULL;
}