T.c 3.68 KB
Newer Older
1
#include "T.h"
2
#include "T_messages.txt.h"
3 4 5 6 7 8 9 10
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
Cedric Roux's avatar
Cedric Roux committed
11
#include <sys/socket.h>
12 13 14 15 16 17 18 19 20 21 22 23 24

/* array used to activate/disactivate a log */
static int T_IDs[T_NUMBER_OF_IDS];
int *T_active = T_IDs;

static int T_socket;

/* T_cache
 * - the T macro picks up the head of freelist and marks it busy
 * - the T sender thread periodically wakes up and sends what's to be sent
 */
volatile int _T_freelist_head;
volatile int *T_freelist_head = &_T_freelist_head;
25
T_cache_t *T_cache;
26 27 28 29 30 31

static void get_message(int s)
{
  char t;
  int l;
  int id;
Cedric Roux's avatar
Cedric Roux committed
32
  int is_on;
33 34 35 36 37 38 39 40 41 42 43 44 45 46

  if (read(s, &t, 1) != 1) abort();
printf("got mess %d\n", t);
  switch (t) {
  case 0:
    /* toggle all those IDs */
    /* optimze? (too much syscalls) */
    if (read(s, &l, sizeof(int)) != sizeof(int)) abort();
    while (l) {
      if (read(s, &id, sizeof(int)) != sizeof(int)) abort();
      T_IDs[id] = 1 - T_IDs[id];
      l--;
    }
    break;
Cedric Roux's avatar
Cedric Roux committed
47 48 49 50 51 52 53 54 55 56 57 58
  case 1:
    /* set IDs as given */
    /* optimize? */
    if (read(s, &l, sizeof(int)) != sizeof(int)) abort();
    id = 0;
    while (l) {
      if (read(s, &is_on, sizeof(int)) != sizeof(int)) abort();
      T_IDs[id] = is_on;
      id++;
      l--;
    }
    break;
59
  case 2: break; /* do nothing, this message is to wait for local tracer */
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
  }
}

static void *T_receive_thread(void *_)
{
  while (1) get_message(T_socket);
  return NULL;
}

static void new_thread(void *(*f)(void *), void *data)
{
  pthread_t t;
  pthread_attr_t att;

  if (pthread_attr_init(&att))
    { fprintf(stderr, "pthread_attr_init err\n"); exit(1); }
  if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED))
    { fprintf(stderr, "pthread_attr_setdetachstate err\n"); exit(1); }
  if (pthread_create(&t, &att, f, data))
    { fprintf(stderr, "pthread_create err\n"); exit(1); }
  if (pthread_attr_destroy(&att))
    { fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); }
}

Cedric Roux's avatar
Cedric Roux committed
84 85 86 87 88
/* defined in local_tracer.c */
void T_local_tracer_main(int remote_port, int wait_for_tracer,
    int local_socket);

void T_init(int remote_port, int wait_for_tracer)
89
{
Cedric Roux's avatar
Cedric Roux committed
90
  int socket_pair[2];
91 92
  int s;
  int T_shm_fd;
93 94
  unsigned char *buf;
  int len;
Cedric Roux's avatar
Cedric Roux committed
95
  int f;
96

Cedric Roux's avatar
Cedric Roux committed
97 98
  if (socketpair(AF_UNIX, SOCK_STREAM, 0, socket_pair))
    { perror("socketpair"); abort(); }
99

Cedric Roux's avatar
Cedric Roux committed
100 101 102 103 104
  f = fork(); if (f == -1) abort();
  if (f == 0) {
    close(socket_pair[1]);
    T_local_tracer_main(remote_port, wait_for_tracer, socket_pair[0]);
    exit(0);
105
  }
Cedric Roux's avatar
Cedric Roux committed
106
  close(socket_pair[0]);
107

Cedric Roux's avatar
Cedric Roux committed
108
  s = socket_pair[1];
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
  /* wait for first message - initial list of active T events */
  get_message(s);

  T_socket = s;

  /* setup shared memory */
  T_shm_fd = shm_open(T_SHM_FILENAME, O_RDWR /*| O_SYNC*/, 0666);
  shm_unlink(T_SHM_FILENAME);
  if (T_shm_fd == -1) { perror(T_SHM_FILENAME); abort(); }
  T_cache = mmap(NULL, T_CACHE_SIZE * sizeof(T_cache_t),
                 PROT_READ | PROT_WRITE, MAP_SHARED, T_shm_fd, 0);
  if (T_cache == NULL)
    { perror(T_SHM_FILENAME); abort(); }
  close(T_shm_fd);

  new_thread(T_receive_thread, NULL);
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139

  /* trace T_message.txt
   * Send several messages -1 with content followed by message -2.
   * We can't use the T macro directly, events -1 and -2 are special.
   */
  buf = T_messages_txt;
  len = T_messages_txt_len;
  while (len) {
    int send_size = len;
    if (send_size > T_PAYLOAD_MAXSIZE - sizeof(int))
      send_size = T_PAYLOAD_MAXSIZE - sizeof(int);
    do {
      T_LOCAL_DATA
      T_HEADER(T_ID(-1));
      T_PUT_buffer(1, ((T_buffer){addr:(buf), length:(len)}));
140
      T_COMMIT();
141 142 143 144 145 146 147
    } while (0);
    buf += send_size;
    len -= send_size;
  }
  do {
    T_LOCAL_DATA
    T_HEADER(T_ID(-2));
148
    T_COMMIT();
149
  } while (0);
150
}