Changeset 35019 for platform/mysql

Show
Ignore:
Timestamp:
08/24/09 14:36:32 (5 years ago)
Author:
kazuho
Message:

update picoev

Location:
platform/mysql/mycached/trunk
Files:
7 modified

Legend:

Unmodified
Added
Removed
  • platform/mysql/mycached/trunk/mycached.cc

    r35004 r35019  
    505505  picoev_add(loop, sock, PICOEV_READ, 0, accept_conn, thd); 
    506506  while (1) { 
    507     picoev_loop_once(loop, 0); 
     507    picoev_loop_once(loop, 60); 
    508508  } 
    509509  picoev_destroy_loop(loop); 
  • platform/mysql/mycached/trunk/mycached.hh

    r35004 r35019  
    3434#include "sql_select.h" 
    3535 
    36 #define NUM_THREADS 4 
     36#define NUM_THREADS 1 
    3737#define MAX_FDS 1024 
    3838#define TIMEOUT_SECS 3600 
  • platform/mysql/mycached/trunk/mycached_as_udf.cc

    r35004 r35019  
    2121#include "mycached.cc" 
    2222extern "C" { 
    23 #include "picoev_select.c" 
     23#ifdef MYCACHED_USE_SELECT 
     24# include "picoev_select.c" 
     25#elif defined(MYCACHED_USE_KQUEUE) 
     26# include "picoev_kqueue.c" 
     27#elif defined(MYCACHED_USE_EPOLL) 
     28# include "picoev_epoll.c" 
     29#else 
     30# error "define one of: MYCACHED_USE_SELECT, MYCACHED_USE_KQUEUE, MYCACHED_USE_EPOLL" 
     31#endif 
    2432} 
    2533 
  • platform/mysql/mycached/trunk/picoev.h

    r35006 r35019  
    4242#include <limits.h> 
    4343#include <stdlib.h> 
     44#include <string.h> 
    4445#include <time.h> 
    4546 
     
    6667#define PICOEV_TIMEOUT 4 
    6768   
    68   typedef unsigned int picoev_loop_id_t; 
     69#define PICOEV_TIMEOUT_IDX_UNUSED (UCHAR_MAX) 
     70   
     71  typedef unsigned short picoev_loop_id_t; 
    6972   
    7073  typedef struct picoev_loop_st picoev_loop; 
     
    7578  typedef struct picoev_fd_st { 
    7679    /* use accessors! */ 
    77     /* should keep the size to 16 bytes on 32-bit arch, 32 bytes on 64-bit */ 
     80    /* TODO adjust the size to match that of a cache line */ 
    7881    picoev_handler* callback; 
    7982    void* cb_arg; 
    8083    picoev_loop_id_t loop_id; 
    81     short events; 
    82     short timeout_idx; /* -1 if not used, otherwise index of timeout_vec */ 
     84    char events; 
     85    unsigned char timeout_idx; /* PICOEV_TIMEOUT_IDX_UNUSED if not used */ 
     86    int _backend; /* can be used by the backend (never ever touched by core) */ 
    8387  } picoev_fd; 
    8488   
     
    109113  extern picoev_globals picoev; 
    110114   
     115  /* creates a new event loop (defined by each backend) */ 
     116  picoev_loop* picoev_create_loop(int max_timeout); 
     117   
     118  /* destroys a loop (defined by each backend) */ 
     119  int picoev_destroy_loop(picoev_loop* loop); 
     120   
     121  /* internal: initializes the backend */ 
     122  int picoev_init_backend(void); 
     123   
     124  /* internal: destroys the backend */ 
     125  int picoev_deinit_backend(void); 
     126   
     127  /* internal: updates events to be watched (defined by each backend) */ 
     128  int picoev_update_events_internal(picoev_loop* loop, int fd, int events); 
     129   
     130  /* internal: poll once and call the handlers (defined by each backend) */ 
     131  int picoev_poll_once_internal(picoev_loop* loop, int max_wait); 
     132   
    111133  /* internal, aligned allocator */ 
    112134  PICOEV_INLINE 
     
    116138      return NULL; 
    117139    } 
     140    memset(*orig_addr, 0, sz); 
    118141    return 
    119142      (void*)PICOEV_RND_UP((unsigned long)*orig_addr, PICOEV_CACHE_LINE_SIZE); 
     
    137160      = PICOEV_RND_UP(picoev.timeout_vec_size, PICOEV_SIMD_BITS) 
    138161      / PICOEV_SHORT_BITS; 
     162    if (picoev_init_backend() != 0) { 
     163      free(picoev.fds); 
     164      picoev.fds = NULL; 
     165      picoev.max_fd = 0; 
     166      return -1; 
     167    } 
    139168    return 0; 
    140169  } 
     
    142171  /* deinitializes picoev */ 
    143172  PICOEV_INLINE 
    144   void picoev_deinit(void) { 
     173  int picoev_deinit(void) { 
    145174    assert(PICOEV_IS_INITED); 
     175    if (picoev_deinit_backend() != 0) { 
     176      return -1; 
     177    } 
    146178    free(picoev._fds_free_addr); 
    147179    picoev.fds = NULL; 
     
    149181    picoev.max_fd = 0; 
    150182    picoev.num_loops = 0; 
    151   } 
    152    
    153   /* creates a new event loop (defined by each backend) */ 
    154   picoev_loop* picoev_create_loop(int max_timeout); 
    155    
    156   /* destroys a loop (defined by each backend) */ 
    157   int picoev_destroy_loop(picoev_loop* loop); 
    158    
    159   /* internal: updates events to be watched (defined by each backend) */ 
    160   int picoev_update_events_internal(picoev_loop* loop, int fd, int events); 
    161    
    162   /* internal: poll once and call the handlers (defined by each backend) */ 
    163   int picoev_poll_once_internal(picoev_loop* loop, int max_wait); 
     183    return 0; 
     184  } 
    164185   
    165186  /* updates timeout */ 
     
    173194    target = picoev.fds + fd; 
    174195    /* clear timeout */ 
    175     if (target->timeout_idx != -1) { 
     196    if (target->timeout_idx != PICOEV_TIMEOUT_IDX_UNUSED) { 
    176197      vec = PICOEV_TIMEOUT_VEC_OF(loop, target->timeout_idx); 
    177198      if ((vec[vi] &= ~((unsigned short)SHRT_MIN >> (fd % PICOEV_SHORT_BITS))) 
     
    181202          &= ~((unsigned short)SHRT_MIN >> (vi % PICOEV_SHORT_BITS)); 
    182203      } 
    183       target->timeout_idx = -1; 
     204      target->timeout_idx = PICOEV_TIMEOUT_IDX_UNUSED; 
    184205    } 
    185206    if (secs != 0) { 
     
    211232    target->loop_id = loop->loop_id; 
    212233    target->events = 0; 
    213     target->timeout_idx = -1; 
    214     if (events != 0 && picoev_update_events_internal(loop, fd, events) != 0) { 
     234    target->timeout_idx = PICOEV_TIMEOUT_IDX_UNUSED; 
     235    if (events != 0 
     236        && picoev_update_events_internal(loop, fd, events) != 0) { 
    215237      target->loop_id = 0; 
    216238      return -1; 
     
    316338                  picoev_fd* fd = picoev.fds + k; 
    317339                  assert(fd->loop_id == loop->loop_id); 
     340                  fd->timeout_idx = PICOEV_TIMEOUT_IDX_UNUSED; 
    318341                  (*fd->callback)(loop, k, PICOEV_TIMEOUT, fd->cb_arg); 
    319342                } 
  • platform/mysql/mycached/trunk/picoev_epoll.c

    r35002 r35019  
    3535  picoev_loop loop; 
    3636  int epfd; 
     37  int changed_fds; /* -1 if none */ 
    3738  struct epoll_event events[1024]; 
    3839} picoev_loop_epoll; 
    3940 
     41#define BACKEND_GET_NEXT_FD(backend) ((backend) >> 8) 
     42#define BACKEND_GET_OLD_EVENTS(backend) ((char)backend) 
     43#define BACKEND_BUILD(nextfd, oldevents) (((nextfd) << 8) | (oldevents)) 
     44 
     45#define CALL_EPOLL(epfd, m, fd, e) {               \ 
     46    int _epoll_ret = epoll_ctl(epfd, m, fd, e);    \ 
     47    assert(m == EPOLL_CTL_DEL || _epoll_ret == 0); \ 
     48  } 
     49   
    4050picoev_globals picoev; 
    4151 
    42 int picoev_update_events_internal(picoev_loop* _loop, int fd, int events) 
     52__inline void picoev_call_epoll(picoev_loop_epoll* loop, int fd, 
     53                                picoev_fd* target) 
    4354{ 
    44   picoev_loop_epoll* loop = (picoev_loop_epoll*)_loop; 
    45   int old_events = picoev.fds[fd].events; 
    46    
    47   assert(PICOEV_FD_BELONGS_TO_LOOP(&loop->loop, fd)); 
    48    
    49 #define CTL(m, e)                             \ 
    50   if (epoll_ctl(loop->epfd, m, fd, e) != 0) { \ 
    51     return -1; \ 
    52   } 
    53    
    54   if (events == 0) { 
    55     CTL(EPOLL_CTL_DEL, 0); 
    56   } else { 
    57     struct epoll_event ev; 
    58     ev.events = ((events & PICOEV_READ) != 0 ? EPOLLIN : 0) 
    59       | ((events & PICOEV_WRITE) != 0 ? EPOLLOUT : 0); 
    60     ev.data.fd = fd; 
    61     if (old_events != 0) { 
    62       CTL(EPOLL_CTL_MOD, &ev); 
    63     } else { 
    64       CTL(EPOLL_CTL_ADD, &ev); 
     55  if (loop->loop.loop_id != target->loop_id) { 
     56    /* now used by another thread, disable */ 
     57    CALL_EPOLL(loop->epfd, EPOLL_CTL_DEL, fd, 0); 
     58  } else if (target->_backend != -1) { 
     59    int old_events = BACKEND_GET_OLD_EVENTS(target->_backend); 
     60    if (old_events != target->events) { 
     61      /* apply changes */ 
     62      if (target->events == 0) { 
     63        CALL_EPOLL(loop->epfd, EPOLL_CTL_DEL, fd, 0); 
     64      } else { 
     65        struct epoll_event ev; 
     66        ev.events = ((target->events & PICOEV_READ) != 0 ? EPOLLIN : 0) 
     67          | ((target->events & PICOEV_WRITE) != 0 ? EPOLLOUT : 0); 
     68        ev.data.fd = fd; 
     69        if (old_events != 0) { 
     70          CALL_EPOLL(loop->epfd, EPOLL_CTL_MOD, fd, &ev); 
     71        } else { 
     72          CALL_EPOLL(loop->epfd, EPOLL_CTL_ADD, fd, &ev); 
     73        } 
     74      } 
    6575    } 
    6676  } 
    67    
    68 #undef CTL 
    69    
    70   picoev.fds[fd].events = events; 
    71   return 0; 
    7277} 
    7378 
     
    8691  } 
    8792   
    88   /* init epoll */ 
     93  /* init myself */ 
    8994  if ((loop->epfd = epoll_create(picoev.max_fd)) == -1) { 
    9095    picoev_deinit_loop_internal(&loop->loop); 
     
    9297    return NULL; 
    9398  } 
     99  loop->changed_fds = -1; 
    94100   
    95101  return &loop->loop; 
     
    108114} 
    109115 
     116int picoev_init_backend() 
     117{ 
     118  int i; 
     119   
     120  for (i = 0; i < picoev.max_fd; ++i) { 
     121    picoev.fds[i]._backend = -1; 
     122  } 
     123   
     124  return 0; 
     125} 
     126 
     127int picoev_deinit_backend() 
     128{ 
     129  return 0; 
     130} 
     131 
     132int picoev_update_events_internal(picoev_loop* _loop, int fd, int events) 
     133{ 
     134  picoev_loop_epoll* loop = (picoev_loop_epoll*)_loop; 
     135  picoev_fd* target = picoev.fds + fd; 
     136   
     137  assert(PICOEV_FD_BELONGS_TO_LOOP(&loop->loop, fd)); 
     138   
     139  if (target->events == events) { 
     140    return 0; 
     141  } 
     142   
     143  /* update chain */ 
     144  if (target->_backend == -1) { 
     145    target->_backend = BACKEND_BUILD(loop->changed_fds, target->events); 
     146    loop->changed_fds = fd; 
     147  } 
     148  target->events = events; 
     149   
     150  return 0; 
     151} 
     152 
    110153int picoev_poll_once_internal(picoev_loop* _loop, int max_wait) 
    111154{ 
    112155  picoev_loop_epoll* loop = (picoev_loop_epoll*)_loop; 
    113156  int i, nevents; 
     157   
     158  if (loop->changed_fds != -1) { 
     159    int fd = loop->changed_fds; 
     160    do { 
     161      picoev_fd* target = picoev.fds + fd; 
     162      picoev_call_epoll(loop, fd, target); 
     163      fd = BACKEND_GET_NEXT_FD(target->_backend); 
     164      target->_backend = -1; 
     165    } while (fd != -1); 
     166    loop->changed_fds = -1; 
     167  } 
    114168   
    115169  nevents = epoll_wait(loop->epfd, loop->events, 
     
    128182      (*target->callback)(&loop->loop, event->data.fd, revents, 
    129183                          target->cb_arg); 
     184    } else { 
     185      CALL_EPOLL(loop->epfd, EPOLL_CTL_DEL, event->data.fd, 0); 
    130186    } 
    131187  } 
  • platform/mysql/mycached/trunk/picoev_kqueue.c

    r35002 r35019  
    4747picoev_globals picoev; 
    4848 
    49 int picoev_update_events_internal(picoev_loop* _loop, int fd, int events) 
    50 { 
    51   picoev_loop_kqueue* loop = (picoev_loop_kqueue*)_loop; 
    52    
    53   assert(PICOEV_FD_BELONGS_TO_LOOP(&loop->loop, fd)); 
    54    
    55 #define SET(ev, cmd)                                      \ 
    56   EV_SET(loop->ev_queue + loop->ev_queue_off++, fd,       \ 
    57          ((ev & PICOEV_READ) != 0 ? EVFILT_READ : 0)      \ 
    58          | ((ev & PICOEV_WRITE) != 0 ? EVFILT_WRITE : 0), \ 
    59          cmd, 0, 0, NULL) 
    60    
    61   if (picoev.fds[fd].events != 0) { 
    62     SET(picoev.fds[fd].events, EV_ADD | EV_ENABLE); 
    63   } 
    64   if (events != 0) { 
    65     SET(events, EV_ADD); 
    66   } 
    67    
    68 #undef SET  
    69    
    70   /* should call imediately if the user might be going to close the socket */ 
    71   if (events == 0 || loop->ev_queue_off + 2 >= EV_QUEUE_SZ) { 
    72     int r = kevent(loop->kq, loop->ev_queue, loop->ev_queue_off, NULL, 0, NULL); 
    73     assert(r == 0); 
    74     loop->ev_queue_off = 0; 
    75   } 
    76    
    77   picoev.fds[fd].events = events; 
    78   return 0; 
    79 } 
    80  
    8149picoev_loop* picoev_create_loop(int max_timeout) 
    8250{ 
     
    11684} 
    11785 
     86int picoev_init_backend() 
     87{ 
     88  return 0; 
     89} 
     90 
     91int picoev_deinit_backend() 
     92{ 
     93  return 0; 
     94} 
     95 
     96int picoev_update_events_internal(picoev_loop* _loop, int fd, int events) 
     97{ 
     98  picoev_loop_kqueue* loop = (picoev_loop_kqueue*)_loop; 
     99   
     100  assert(PICOEV_FD_BELONGS_TO_LOOP(&loop->loop, fd)); 
     101   
     102#define SET(ev, cmd)                                      \ 
     103  EV_SET(loop->ev_queue + loop->ev_queue_off++, fd,       \ 
     104         ((ev & PICOEV_READ) != 0 ? EVFILT_READ : 0)      \ 
     105         | ((ev & PICOEV_WRITE) != 0 ? EVFILT_WRITE : 0), \ 
     106         cmd, 0, 0, NULL) 
     107   
     108  if (picoev.fds[fd].events != 0) { 
     109    SET(picoev.fds[fd].events, EV_ADD | EV_ENABLE); 
     110  } 
     111  if (events != 0) { 
     112    SET(events, EV_ADD); 
     113  } 
     114   
     115#undef SET  
     116   
     117  /* should call imediately if the user might be going to close the socket */ 
     118  if (events == 0 || loop->ev_queue_off + 2 >= EV_QUEUE_SZ) { 
     119    int r = kevent(loop->kq, loop->ev_queue, loop->ev_queue_off, NULL, 0, NULL); 
     120    assert(r == 0); 
     121    loop->ev_queue_off = 0; 
     122  } 
     123   
     124  picoev.fds[fd].events = events; 
     125  return 0; 
     126} 
     127 
    118128int picoev_poll_once_internal(picoev_loop* _loop, int max_wait) 
    119129{ 
  • platform/mysql/mycached/trunk/picoev_select.c

    r35002 r35019  
    3333picoev_globals picoev; 
    3434 
    35 int picoev_update_events_internal(picoev_loop* loop, int fd, int events) 
    36 { 
    37   picoev.fds[fd].events = events; 
    38   return 0; 
    39 } 
    40  
    4135picoev_loop* picoev_create_loop(int max_timeout) 
    4236{ 
     
    5953  picoev_deinit_loop_internal(loop); 
    6054  free(loop); 
     55  return 0; 
     56} 
     57 
     58int picoev_init_backend() 
     59{ 
     60  return 0; 
     61} 
     62 
     63int picoev_deinit_backend() 
     64{ 
     65  return 0; 
     66} 
     67 
     68int picoev_update_events_internal(picoev_loop* loop, int fd, int events) 
     69{ 
     70  picoev.fds[fd].events = events; 
    6171  return 0; 
    6272}