Changeset b406d071 in rtems


Ignore:
Timestamp:
Oct 1, 2019, 12:16:34 PM (3 weeks ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
feb27f9
Parents:
f88025a
git-author:
Sebastian Huber <sebastian.huber@…> (10/01/19 12:16:34)
git-committer:
Sebastian Huber <sebastian.huber@…> (10/11/19 06:55:49)
Message:

libtest: Do all output in test runner

This ensures that lines are output atomically if they are produced by
different other contexts, e.g. interrupts, other processors, other
threads.

Update #3199.

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • cpukit/include/t.h

    rf88025a rb406d071  
    22002200typedef struct {
    22012201        const char *name;
     2202        char *buf;
     2203        size_t buf_size;
    22022204        T_putchar putchar;
    22032205        void *putchar_arg;
  • cpukit/libtest/t-test.c

    rf88025a rb406d071  
    4848#endif /* __rtems__ */
    4949
    50 #define T_LINE_SIZE 120
     50#define T_LINE_SIZE 128
    5151
    5252#define T_SCOPE_SIZE 5
     
    5454typedef struct {
    5555        pthread_spinlock_t lock;
     56        char *buf;
     57        unsigned int buf_mask;
     58        atomic_uint buf_head;
     59        atomic_uint buf_tail;
    5660        void (*putchar)(int, void *);
    5761        void *putchar_arg;
     
    8286static T_context T_instance;
    8387
    84 static int
    85 T_do_vprintf(T_context *ctx, char const *fmt, va_list ap)
    86 {
    87         return _IO_Vprintf(ctx->putchar, ctx->putchar_arg, fmt, ap);
    88 }
    89 
    90 int
    91 T_vprintf(char const *fmt, va_list ap)
    92 {
    93         return T_do_vprintf(&T_instance, fmt, ap);
    94 }
    95 
    9688typedef struct {
    9789        char *s;
     
    10294T_putchar_string(int c, void *arg)
    10395{
    104         T_putchar_string_context *ctx;
     96        T_putchar_string_context *sctx;
    10597        char *s;
    10698        size_t n;
    10799
    108         ctx = arg;
    109         s = ctx->s;
    110         n = ctx->n;
     100        sctx = arg;
     101        s = sctx->s;
     102        n = sctx->n;
    111103
    112104        if (n == 1) {
     
    120112        }
    121113
    122         ctx->s = s;
    123         ctx->n = n;
     114        sctx->s = s;
     115        sctx->n = n;
    124116}
    125117
     
    129121        va_list ap;
    130122        int len;
    131         T_putchar_string_context ctx = {
     123        T_putchar_string_context sctx = {
    132124                .s = s,
    133125                .n = n
     
    135127
    136128        va_start(ap, fmt);
    137         len = _IO_Vprintf(T_putchar_string, &ctx, fmt, ap);
     129        len = _IO_Vprintf(T_putchar_string, &sctx, fmt, ap);
    138130        va_end(ap);
    139131
    140         if (ctx.n > 0) {
    141                 *ctx.s = '\0';
     132        if (sctx.n > 0) {
     133                *sctx.s = '\0';
     134        }
     135
     136        return len;
     137}
     138
     139static int
     140T_vprintf_direct(char const *fmt, va_list ap)
     141{
     142        T_context *ctx;
     143        unsigned int head;
     144        unsigned int tail;
     145
     146        ctx = &T_instance;
     147
     148        head = atomic_load_explicit(&ctx->buf_head, memory_order_acquire);
     149        tail = atomic_load_explicit(&ctx->buf_tail, memory_order_relaxed);
     150
     151        while (head != tail) {
     152                (*ctx->putchar)(ctx->buf[tail], ctx->putchar_arg);
     153                tail = (tail + 1) & ctx->buf_mask;
     154        }
     155
     156        atomic_store_explicit(&ctx->buf_tail, tail, memory_order_relaxed);
     157
     158        return _IO_Vprintf(ctx->putchar, ctx->putchar_arg, fmt, ap);
     159}
     160
     161static int
     162T_vprintf_buffered(char const *fmt, va_list ap)
     163{
     164        unsigned int len;
     165        T_context *ctx;
     166        char buf[T_LINE_SIZE];
     167        T_putchar_string_context sctx = {
     168                .s = buf,
     169                .n = sizeof(buf)
     170        };
     171        unsigned int head;
     172        unsigned int tail;
     173        unsigned int mask;
     174        unsigned int capacity;
     175
     176        len = (unsigned int)_IO_Vprintf(T_putchar_string, &sctx, fmt, ap);
     177
     178        if (len >= sizeof(buf)) {
     179                len = sizeof(buf) - 1;
     180        }
     181
     182        ctx = &T_instance;
     183        pthread_spin_lock(&ctx->lock);
     184        head = atomic_load_explicit(&ctx->buf_head, memory_order_relaxed);
     185        tail = atomic_load_explicit(&ctx->buf_tail, memory_order_relaxed);
     186        mask = ctx->buf_mask;
     187        capacity = (tail - head - 1) & mask;
     188
     189        if (len <= capacity) {
     190                unsigned int todo;
     191                char *c;
     192
     193                todo = len;
     194                c = buf;
     195
     196                while (todo > 0) {
     197                        ctx->buf[head] = *c;
     198                        head = (head + 1) & mask;
     199                        --todo;
     200                        ++c;
     201                }
     202
     203                atomic_store_explicit(&ctx->buf_head, head,
     204                    memory_order_release);
     205        } else {
     206                /* If it does not fit into the buffer, discard everything */
     207                len = 0;
     208        }
     209
     210        pthread_spin_unlock(&ctx->lock);
     211        return (int)len;
     212}
     213
     214int
     215T_vprintf(char const *fmt, va_list ap)
     216{
     217        int len;
     218
     219        if (T_is_runner()) {
     220                len = T_vprintf_direct(fmt, ap);
     221        } else {
     222                len = T_vprintf_buffered(fmt, ap);
    142223        }
    143224
     
    605686
    606687        ctx->config = config;
     688        ctx->buf = config->buf;
     689
     690        if (config->buf_size > 0 &&
     691            (config->buf_size & (config->buf_size - 1)) == 0) {
     692                ctx->buf_mask = config->buf_size - 1;
     693        } else {
     694                ctx->buf_mask = 0;
     695        }
     696
     697        atomic_store_explicit(&ctx->buf_head, 0, memory_order_relaxed);
     698        ctx->buf_tail = 0;
    607699        ctx->putchar = config->putchar;
    608700        ctx->putchar_arg = config->putchar_arg;
  • testsuites/libtests/ttest01/init.c

    rf88025a rb406d071  
    139139}
    140140
     141static char buffer[512];
     142
    141143static const T_action actions[] = {
    142144        T_report_hash_sha256,
     
    146148static const T_config config = {
    147149        .name = "ttest01",
     150        .buf = buffer,
     151        .buf_size = sizeof(buffer),
    148152        .putchar = test_putchar,
    149153        .putchar_arg = &test_instance,
Note: See TracChangeset for help on using the changeset viewer.