Exemplo n.º 1
0
void addPacketToTransferBuffer(flowOutputState state, FlowEventPacket packet,
		int32_t flowNumber) {
	if (packet == NULL) {
		// There was nothing in this mainloop run: return
		return;
	}

	caerEventPacketHeader header = &packet->packetHeader;

	// If no valid events are present, there is nothing to add
	if (caerEventPacketHeaderGetEventValid(header) == 0) {
		return;
	}
	if (flowNumber == 0) {
		return;
	}

	// Allocate memory for new flow event packet
	FlowEventPacket copy = malloc(sizeof(struct flow_event_packet));
	if (copy == NULL) {
			caerLog(CAER_LOG_ERROR, SUBSYSTEM_UART,"Failed to copy event packet.");
		return;
	}

	// Copy header information
	copy->packetHeader = packet->packetHeader;
	copy->packetHeader.eventNumber = flowNumber;
	copy->packetHeader.eventValid = flowNumber;
	copy->events = malloc(sizeof(struct flow_event) * (size_t) flowNumber);

	// Copy events
	int j = 0;
	for (int i = 0; i < header->eventNumber; i++) {
		FlowEvent e = &packet->events[i];
		if (e->hasFlow) {
			copy->events[j] = *e;
			j++;
		}
	}

	// Verify number of events copied
	if (j != flowNumber) {
		caerLog(CAER_LOG_ERROR, SUBSYSTEM_FILE,
				"Copied %d events while number of flow events is %d.",
				j, flowNumber);
		flowEventPacketFree(copy);
		return;
	}

	if (!ringBufferPut(state->buffer, copy)) {
		flowEventPacketFree(copy);
		caerLog(CAER_LOG_ALERT, SUBSYSTEM_UART,"Failed to add event packet to ring buffer.");
		return;
	}
}
Exemplo n.º 2
0
static void onMsgTimer (struct work_struct *work) {
	if (controlState > 0) { controlState = 2; return; }
	printk ("queued work gets executed\n");

	if (!queue_delayed_work (msgTimerQueue, &fifo_put_timer, HZ)) {
		printk ("queue_delayed_work failed!\n");
	}

	static int i = 0;
	ringBufferPut(fifoDev->rb, "Work %d", ++i);
}
Exemplo n.º 3
0
/**
 * Copy event packets to the ring buffer for transfer to the output handler thread.
 *
 * @param state output module state.
 * @param packetsListSize the length of the variable-length argument list of event packets.
 * @param packetsList a variable-length argument list of event packets.
 */
static void copyPacketsToTransferRing(outputCommonState state, size_t packetsListSize, va_list packetsList) {
	caerEventPacketHeader packets[packetsListSize];
	size_t packetsSize = 0;

	// Count how many packets are really there, skipping empty event packets.
	for (size_t i = 0; i < packetsListSize; i++) {
		caerEventPacketHeader packetHeader = va_arg(packetsList, caerEventPacketHeader);

		// Found non-empty event packet.
		if (packetHeader != NULL) {
			// Get source information from the event packet.
			int16_t eventSource = caerEventPacketHeaderGetEventSource(packetHeader);

			// Check that source is unique.
			int16_t sourceID = I16T(atomic_load_explicit(&state->sourceID, memory_order_relaxed));

			if (sourceID == -1) {
				state->sourceInfoNode = caerMainloopGetSourceInfo(U16T(eventSource));
				if (state->sourceInfoNode == NULL) {
					// This should never happen, but we handle it gracefully.
					caerLog(CAER_LOG_ERROR, state->parentModule->moduleSubSystemString,
						"Failed to get source info to setup output module.");
					return;
				}

				atomic_store(&state->sourceID, eventSource); // Remember this!
			}
			else if (sourceID != eventSource) {
				caerLog(CAER_LOG_ERROR, state->parentModule->moduleSubSystemString,
					"An output module can only handle packets from the same source! "
						"A packet with source %" PRIi16 " was sent, but this output module expects only packets from source %" PRIi16 ".",
					eventSource, sourceID);
				continue;
			}

			// Source ID is correct, packet is not empty, we got it!
			packets[packetsSize++] = packetHeader;
		}
	}

	// There was nothing in this mainloop run!
	if (packetsSize == 0) {
		return;
	}

	// Allocate memory for event packet array structure that will get passed to output handler thread.
	caerEventPacketContainer eventPackets = caerEventPacketContainerAllocate((int32_t) packetsSize);
	if (eventPackets == NULL) {
		return;
	}

	// Handle the valid only flag here, that way we don't have to do another copy and
	// process it in the output handling thread. We get the value once here, so we do
	// the same for all packets from the same mainloop run, avoiding mid-way changes.
	bool validOnly = atomic_load_explicit(&state->validOnly, memory_order_relaxed);

	// Now copy each event packet and send the array out. Track how many packets there are.
	size_t idx = 0;

	for (size_t i = 0; i < packetsSize; i++) {
		if (validOnly) {
			caerEventPacketContainerSetEventPacket(eventPackets, (int32_t) idx,
				caerCopyEventPacketOnlyValidEvents(packets[i]));
		}
		else {
			caerEventPacketContainerSetEventPacket(eventPackets, (int32_t) idx,
				caerCopyEventPacketOnlyEvents(packets[i]));
		}

		if (caerEventPacketContainerGetEventPacket(eventPackets, (int32_t) idx) == NULL) {
			// Failed to copy packet. Signal but try to continue anyway.
			if ((validOnly && (caerEventPacketHeaderGetEventValid(packets[i]) == 0))
				|| (!validOnly && (caerEventPacketHeaderGetEventNumber(packets[i]) == 0))) {
				caerLog(CAER_LOG_NOTICE, state->parentModule->moduleSubSystemString,
					"Submitted empty event packet to output. Ignoring empty event packet.");
			}
			else {
				caerLog(CAER_LOG_ERROR, state->parentModule->moduleSubSystemString,
					"Failed to copy event packet to output.");
			}
		}
		else {
			idx++;
		}
	}

	// We might have failed to copy all packets (unlikely).
	if (idx == 0) {
		caerEventPacketContainerFree(eventPackets);

		return;
	}

	// Reset packet container size so we only consider the packets we managed
	// to successfully copy.
	caerEventPacketContainerSetEventPacketsNumber(eventPackets, (int32_t) idx);

	retry: if (!ringBufferPut(state->transferRing, eventPackets)) {
		if (atomic_load_explicit(&state->keepPackets, memory_order_relaxed)) {
			// Retry forever if requested.
			goto retry;
		}

		caerEventPacketContainerFree(eventPackets);

		caerLog(CAER_LOG_INFO, state->parentModule->moduleSubSystemString,
			"Failed to put packet's array copy on transfer ring-buffer: full.");
		return;
	}
}