Skip to content
Snippets Groups Projects
Select Git revision
  • develop default
  • 2023.w43
  • 2023.w42
  • 2023.w41
  • 2023.w40
  • 2023.w39
  • 2023.w38
  • 2023.w37
  • 2023.w36
  • 2023.w34
  • 2023.w33
  • 2023.w32
  • v2.0.0
  • 2023.w31
  • 2023.w30
  • 2023.w29
  • 2023.w28
  • 2023.w27
  • 2023.w26
  • 2023.w25
  • 2023.w24
21 results

T.c

Blame
  • user avatar
    Cedric Roux authored
    This message sends configuration for all events.
    e6d5f22c
    History
    T.c 4.07 KiB
    #include "T.h"
    #include <string.h>
    #include <netinet/ip.h>
    #include <arpa/inet.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <pthread.h>
    #include <stdio.h>
    #include <sys/mman.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    /* 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;
    int T_busylist_head;
    T_cache_t _T_cache[T_CACHE_SIZE];
    T_cache_t *T_cache = _T_cache;
    
    static void get_message(int s)
    {
      char t;
      int l;
      int id;
      int is_on;
    
      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;
      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;
      }
    }
    
    #ifndef T_USE_SHARED_MEMORY
    
    static void *T_send_thread(void *_)
    {
      while (1) {
        usleep(5000);
        __sync_synchronize();
        while (T_cache[T_busylist_head].busy) {
          char *b;
          int l;
          /* TODO: be sure about those memory barriers - in doubt one is
           * put here too
           */
          __sync_synchronize();
          b = T_cache[T_busylist_head].buffer;
          l = T_cache[T_busylist_head].length;
          while (l) {
            int done = write(T_socket, b, l);
            if (done <= 0) {
              printf("%s:%d:%s: error sending to socket\n",
                     __FILE__, __LINE__, __FUNCTION__);
              abort();
            }
            b += done;
            l -= done;
          }
          T_cache[T_busylist_head].busy = 0;
          T_busylist_head++;
          T_busylist_head &= T_CACHE_SIZE - 1;
        }
      }
      return NULL;
    }
    
    #endif /* T_USE_SHARED_MEMORY */
    
    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); }
    }
    
    void T_connect_to_tracer(char *addr, int port)
    {
      struct sockaddr_in a;
      int s;
    #ifdef T_USE_SHARED_MEMORY
      int T_shm_fd;
    #endif
    
      if (strcmp(addr, "127.0.0.1") != 0) {
        printf("error: local tracer must be on same host\n");
        abort();
      }
    
      printf("connecting to local tracer on port %d\n", port);
    again:
      s = socket(AF_INET, SOCK_STREAM, 0);
      if (s == -1) { perror("socket"); exit(1); }
    
      a.sin_family = AF_INET;
      a.sin_port = htons(port);
      a.sin_addr.s_addr = inet_addr("127.0.0.1");
    
      if (connect(s, (struct sockaddr *)&a, sizeof(a)) == -1) {
        perror("connect");
        close(s);
        printf("trying again in 1s\n");
        sleep(1);
        goto again;
      }
    
      /* wait for first message - initial list of active T events */
      get_message(s);
    
      T_socket = s;
    
    #ifdef T_USE_SHARED_MEMORY
      /* 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);
    #endif
    
    #ifndef T_USE_SHARED_MEMORY
      new_thread(T_send_thread, NULL);
    #endif
      new_thread(T_receive_thread, NULL);
    }