Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:13

0001 /*
0002  * SPDX-License-Identifier: BSD-2-Clause
0003  *
0004  * Copyright (C) 2018, 2024 embedded brains GmbH & Co. KG
0005  *
0006  * Redistribution and use in source and binary forms, with or without
0007  * modification, are permitted provided that the following conditions
0008  * are met:
0009  * 1. Redistributions of source code must retain the above copyright
0010  *    notice, this list of conditions and the following disclaimer.
0011  * 2. Redistributions in binary form must reproduce the above copyright
0012  *    notice, this list of conditions and the following disclaimer in the
0013  *    documentation and/or other materials provided with the distribution.
0014  *
0015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0025  * POSSIBILITY OF SUCH DAMAGE.
0026  */
0027 
0028 /*
0029  * This file must be compatible to general purpose POSIX system, e.g. Linux,
0030  * FreeBSD.  It may be used for utility programs.
0031  */
0032 
0033 #ifndef _RTEMS_RECORDCLIENT_H
0034 #define _RTEMS_RECORDCLIENT_H
0035 
0036 #include "recorddata.h"
0037 
0038 #include <stdbool.h>
0039 #include <stddef.h>
0040 
0041 #ifdef __cplusplus
0042 extern "C" {
0043 #endif /* __cplusplus */
0044 
0045 /**
0046  * @addtogroup RTEMSRecord
0047  *
0048  * @{
0049  */
0050 
0051 #define RTEMS_RECORD_CLIENT_MAXIMUM_CPU_COUNT 32
0052 
0053 typedef enum {
0054   RTEMS_RECORD_CLIENT_SUCCESS,
0055   RTEMS_RECORD_CLIENT_ERROR_INVALID_MAGIC,
0056   RTEMS_RECORD_CLIENT_ERROR_UNKNOWN_FORMAT,
0057   RTEMS_RECORD_CLIENT_ERROR_UNSUPPORTED_VERSION,
0058   RTEMS_RECORD_CLIENT_ERROR_UNSUPPORTED_CPU,
0059   RTEMS_RECORD_CLIENT_ERROR_UNSUPPORTED_CPU_MAX,
0060   RTEMS_RECORD_CLIENT_ERROR_DOUBLE_CPU_MAX,
0061   RTEMS_RECORD_CLIENT_ERROR_DOUBLE_PER_CPU_COUNT,
0062   RTEMS_RECORD_CLIENT_ERROR_NO_CPU_MAX,
0063   RTEMS_RECORD_CLIENT_ERROR_NO_MEMORY,
0064   RTEMS_RECORD_CLIENT_ERROR_PER_CPU_ITEMS_OVERFLOW
0065 } rtems_record_client_status;
0066 
0067 typedef rtems_record_client_status ( *rtems_record_client_handler )(
0068   uint64_t            bt,
0069   uint32_t            cpu,
0070   rtems_record_event  event,
0071   uint64_t            data,
0072   void               *arg
0073 );
0074 
0075 typedef struct {
0076   uint64_t uptime_bt;
0077   uint32_t time_last;
0078   uint64_t time_accumulated;
0079 } rtems_record_client_uptime;
0080 
0081 /**
0082  * @brief This constant defines the maximum capacity of the hold back item
0083  *   storage in case a reallocation is necessary.
0084  */
0085 #define RTEMS_RECORD_CLIENT_HOLD_BACK_REALLOCATION_LIMIT 0x100000
0086 
0087 typedef struct {
0088   /**
0089    * @brief Event time to uptime maintenance.
0090    */
0091   rtems_record_client_uptime uptime;
0092 
0093   /**
0094    * @brief The binary time of the last item.
0095    */
0096   uint64_t last_bt;
0097 
0098   /**
0099    * @brief Last RTEMS_RECORD_UPTIME_LOW data.
0100    */
0101   uint32_t uptime_low;
0102 
0103   /**
0104    * @brief If true, then uptime low value is valid.
0105    */
0106   bool uptime_low_valid;
0107 
0108   /**
0109    * @brief If true, then hold back items.
0110    */
0111   bool hold_back;
0112 
0113   /**
0114    * @brief Storage for hold back items.
0115    *
0116    * Once the time stamp association with the uptime is known, the hold back
0117    * items can be processed.
0118    */
0119   rtems_record_item_64 *items;
0120 
0121   /**
0122    * @brief The item capacity of the hold back storage.
0123    */
0124   size_t item_capacity;
0125 
0126   /**
0127    * @brief The index for the next hold back item.
0128    */
0129   size_t item_index;
0130 } rtems_record_client_per_cpu;
0131 
0132 typedef struct rtems_record_client_context {
0133   uint64_t to_bt_scaler;
0134   rtems_record_client_per_cpu per_cpu[ RTEMS_RECORD_CLIENT_MAXIMUM_CPU_COUNT ];
0135   uint32_t cpu;
0136   uint32_t cpu_count;
0137   uint32_t per_cpu_items;
0138   union {
0139     rtems_record_item_32 format_32;
0140     rtems_record_item_64 format_64;
0141   } item;
0142   size_t todo;
0143   void *pos;
0144   rtems_record_client_status ( *consume )(
0145     struct rtems_record_client_context *,
0146     const void *,
0147     size_t
0148   );
0149   rtems_record_client_handler handler;
0150   void *handler_arg;
0151   size_t data_size;
0152   uint32_t header[ 2 ];
0153   rtems_record_client_status status;
0154 } rtems_record_client_context;
0155 
0156 /**
0157  * @brief Initializes a record client.
0158  *
0159  * The record client consumes a record item stream produces by the record
0160  * server.
0161  *
0162  * @param ctx The record client context to initialize.
0163  * @param handler The handler is invoked for each received record item.
0164  * @param arg The handler argument.
0165  */
0166 rtems_record_client_status rtems_record_client_init(
0167   rtems_record_client_context *ctx,
0168   rtems_record_client_handler  handler,
0169   void                        *arg
0170 );
0171 
0172 /**
0173  * @brief Runs the record client to consume new stream data.
0174  *
0175  * @param ctx The record client context.
0176  * @param buf The buffer with new stream data.
0177  * @param n The size of the buffer.
0178  */
0179 rtems_record_client_status rtems_record_client_run(
0180   rtems_record_client_context *ctx,
0181   const void                  *buf,
0182   size_t                       n
0183 );
0184 
0185 /**
0186  * @brief Drains all internal buffers and frees the allocated resources.
0187  *
0188  * The client context must not be used afterwards.  It can be re-initialized
0189  * via rtems_record_client_init().
0190  *
0191  * @param ctx The record client context.
0192  */
0193 void rtems_record_client_destroy(
0194   rtems_record_client_context *ctx
0195 );
0196 
0197 static inline void rtems_record_client_set_handler(
0198   rtems_record_client_context *ctx,
0199   rtems_record_client_handler  handler
0200 )
0201 {
0202   ctx->handler = handler;
0203 }
0204 
0205 static inline uint64_t rtems_record_client_bintime_to_nanoseconds(
0206   uint64_t bt
0207 )
0208 {
0209   uint64_t ns_per_sec;
0210   uint64_t nanoseconds;
0211 
0212   ns_per_sec = 1000000000ULL;
0213   nanoseconds = ns_per_sec * ( (uint32_t) ( bt >> 32 ) );
0214   nanoseconds += ( ns_per_sec * (uint32_t) bt ) >> 32;
0215 
0216   return nanoseconds;
0217 }
0218 
0219 static inline void rtems_record_client_bintime_to_seconds_and_nanoseconds(
0220   uint64_t  bt,
0221   uint32_t *seconds,
0222   uint32_t *nanoseconds
0223 )
0224 {
0225   uint64_t ns_per_sec;
0226 
0227   ns_per_sec = 1000000000ULL;
0228   *seconds = (uint32_t) ( bt >> 32 );
0229   *nanoseconds = (uint32_t) ( ( ns_per_sec * (uint32_t) bt ) >> 32 );
0230 }
0231 
0232 /** @} */
0233 
0234 #ifdef __cplusplus
0235 }
0236 #endif /* __cplusplus */
0237 
0238 #endif /* _RTEMS_RECORDCLIENT_H */