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; } }
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); }
/** * 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; } }