Ignore:
Timestamp:
07/03/17 16:31:57 (4 years ago)
Author:
Shane Alcock <salcock@…>
Branches:
cachetimestamps, develop, dpdk-ndag, etsilive, master, ndag_format, rc-4.0.2, rc-4.0.3, rc-4.0.4, ringdecrementfix, ringperformance
Children:
8e11beb
Parents:
4578626
Message:

Add support for reading pcapng traces

Also added special macro: IS_LIBTRACE_META_PACKET()
This macro can be used to easily recognise if a "packet" is a
genuine packet record or a meta record (such as a pcapng interface
block or an RT control message).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/trace_parallel.c

    rb606855 red5b2ce  
    343343                        (int) t->tid, prev_state, t->state);
    344344
    345         if (trace->perpkt_thread_states[THREAD_FINISHED] == trace->perpkt_thread_count)
     345        if (trace->perpkt_thread_states[THREAD_FINISHED] == trace->perpkt_thread_count) {
     346                /* Make sure we save our final stats in case someone wants
     347                 * them at the end of their program.
     348                 */
     349
     350                trace_get_statistics(trace, NULL);
    346351                libtrace_change_state(trace, STATE_FINISHED, false);
     352        }
    347353
    348354        pthread_cond_broadcast(&trace->perpkt_cond);
     
    473479                                return READ_MESSAGE;
    474480                }
    475                 t->accepted_packets++;
     481                if (!IS_LIBTRACE_META_PACKET((*packet))) {
     482                        t->accepted_packets++;
     483                }
    476484                if (trace->perpkt_cbs->message_packet)
    477485                        *packet = (*trace->perpkt_cbs->message_packet)(trace, t, trace->global_blob, t->user_data, *packet);
     
    608616        /* The offset to the first NULL packet upto offset */
    609617        int empty = 0;
     618        int j;
    610619
    611620        /* Wait until trace_pstart has been completed */
     
    692701                /* Handle error/message cases */
    693702                if (nb_packets > 0) {
    694                         /* Store the first packet */
    695                         if (packets[0]->error > 0) {
    696                                 store_first_packet(trace, packets[0], t);
     703                        /* Store the first non-meta packet */
     704                        for (j = 0; j < nb_packets; j++) {
     705                                if (t->recorded_first)
     706                                        break;
     707                                if (packets[j]->error > 0) {
     708                                        store_first_packet(trace, packets[j], t);
     709                                }
    697710                        }
    698711                        dispatch_packets(trace, t, packets, nb_packets, &empty,
     
    918931                        tick_hit = true;
    919932                }*/
    920         }
    921         // Doing this inside the lock ensures the first packet is always
    922         // recorded first
    923         if (packets[0]->error > 0) {
    924                 store_first_packet(libtrace, packets[0], t);
     933
     934                // Doing this inside the lock ensures the first packet is
     935                // always recorded first
     936                if (!t->recorded_first && packets[0]->error > 0) {
     937                        store_first_packet(libtrace, packets[0], t);
     938                }
    925939        }
    926940        ASSERT_RET(pthread_mutex_unlock(&libtrace->read_packet_lock), == 0);
     
    9941008void store_first_packet(libtrace_t *libtrace, libtrace_packet_t *packet, libtrace_thread_t *t)
    9951009{
    996         if (!t->recorded_first) {
    997                 libtrace_message_t mesg = {0, {.uint64=0}, NULL};
    998                 struct timeval tv;
    999                 libtrace_packet_t * dup;
    1000 
    1001                 /* We mark system time against a copy of the packet */
    1002                 gettimeofday(&tv, NULL);
    1003                 dup = trace_copy_packet(packet);
    1004 
    1005                 ASSERT_RET(pthread_spin_lock(&libtrace->first_packets.lock), == 0);
    1006                 libtrace->first_packets.packets[t->perpkt_num].packet = dup;
    1007                 memcpy(&libtrace->first_packets.packets[t->perpkt_num].tv, &tv, sizeof(tv));
    1008                 libtrace->first_packets.count++;
    1009 
    1010                 /* Now update the first */
    1011                 if (libtrace->first_packets.count == 1) {
    1012                         /* We the first entry hence also the first known packet */
    1013                         libtrace->first_packets.first = t->perpkt_num;
    1014                 } else {
    1015                         /* Check if we are newer than the previous 'first' packet */
    1016                         size_t first = libtrace->first_packets.first;
    1017                         struct timeval cur_ts = trace_get_timeval(dup);
    1018                         struct timeval first_ts = trace_get_timeval(libtrace->first_packets.packets[first].packet);
    1019                         if (timercmp(&cur_ts, &first_ts, <))
    1020                                 libtrace->first_packets.first = t->perpkt_num;
    1021                 }
    1022                 ASSERT_RET(pthread_spin_unlock(&libtrace->first_packets.lock), == 0);
    1023 
    1024                 mesg.code = MESSAGE_FIRST_PACKET;
    1025                 trace_message_reporter(libtrace, &mesg);
    1026                 trace_message_perpkts(libtrace, &mesg);
    1027                 t->recorded_first = true;
    1028         }
     1010
     1011        libtrace_message_t mesg = {0, {.uint64=0}, NULL};
     1012        struct timeval tv;
     1013        libtrace_packet_t * dup;
     1014
     1015        if (t->recorded_first) {
     1016                return;
     1017        }
     1018
     1019        if (IS_LIBTRACE_META_PACKET(packet)) {
     1020                return;
     1021        }
     1022
     1023        /* We mark system time against a copy of the packet */
     1024        gettimeofday(&tv, NULL);
     1025        dup = trace_copy_packet(packet);
     1026
     1027        ASSERT_RET(pthread_spin_lock(&libtrace->first_packets.lock), == 0);
     1028        libtrace->first_packets.packets[t->perpkt_num].packet = dup;
     1029        memcpy(&libtrace->first_packets.packets[t->perpkt_num].tv, &tv, sizeof(tv));
     1030        libtrace->first_packets.count++;
     1031
     1032        /* Now update the first */
     1033        if (libtrace->first_packets.count == 1) {
     1034                /* We the first entry hence also the first known packet */
     1035                libtrace->first_packets.first = t->perpkt_num;
     1036        } else {
     1037                /* Check if we are newer than the previous 'first' packet */
     1038                size_t first = libtrace->first_packets.first;
     1039                struct timeval cur_ts = trace_get_timeval(dup);
     1040                struct timeval first_ts = trace_get_timeval(libtrace->first_packets.packets[first].packet);
     1041                if (timercmp(&cur_ts, &first_ts, <))
     1042                        libtrace->first_packets.first = t->perpkt_num;
     1043        }
     1044        ASSERT_RET(pthread_spin_unlock(&libtrace->first_packets.lock), == 0);
     1045
     1046        mesg.code = MESSAGE_FIRST_PACKET;
     1047        trace_message_reporter(libtrace, &mesg);
     1048        trace_message_perpkts(libtrace, &mesg);
     1049        t->recorded_first = true;
    10291050}
    10301051
     
    12211242                int64_t initial_offset;
    12221243                int stable = trace_get_first_packet(libtrace, NULL, &first_pkt, &sys_tv);
    1223                 assert(first_pkt);
     1244                if (!first_pkt)
     1245                        return 0;
    12241246                pkt_tv = trace_get_timeval(first_pkt);
    12251247                initial_offset = (int64_t)tv_to_usec(sys_tv) - (int64_t)tv_to_usec(&pkt_tv);
Note: See TracChangeset for help on using the changeset viewer.