Skip to content

Node.js timer #3

@hustxiaoc

Description

@hustxiaoc

a simple timer based on kqueue and min binary heap

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/event.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>

//https://github.com/joyent/libuv/blob/master/src/heap-inl.h
#include "heap-inl.h"

#define container_of(ptr, type, member) \
  ((type *) ((char *) (ptr) - offsetof(type, member)))

const int MAX_EVENT_COUNT = 5000;

typedef struct {
    struct heap_node* heap_node[3];
    int value;
}node_t;

static int less_than(const struct heap_node* ha, const struct heap_node* hb) {
    const node_t* a;
      const node_t* b;

    a = container_of(ha, const node_t, heap_node);
    b = container_of(hb, const node_t, heap_node);

    if (a->value < b->value)
      return 1;
    return 0;
}


int main() {

  struct heap *heap_p = malloc(sizeof(node_t));
  heap_init(heap_p);

  int a[] = {10,9,8,6,7,3,5,4,2};

  int len = sizeof(a)/sizeof(int);
  for(int i=0;i<len;i++){
    node_t *node_p = malloc(sizeof(node_t));
    node_p->value = a[i]*1000;
    heap_insert(heap_p, (struct heap_node*)node_p->heap_node, less_than);
  }


  int fd = socket(PF_INET, SOCK_STREAM,0);
  int kq = kqueue();

  struct kevent changes[1];
  EV_SET(&changes[0], fd, EVFILT_READ, EV_ADD, 0, 0, NULL);

  struct kevent events[MAX_EVENT_COUNT];
  time_t last_time = time(NULL);
  while(heap_p->nelts) {
      node_t *node_p = container_of(heap_p->min, node_t, heap_node);
      struct timespec spec;
      spec.tv_sec = node_p->value / 1000;
      spec.tv_nsec = (node_p->value % 1000) * 1000000;
      kevent(kq, NULL, 0, events, MAX_EVENT_COUNT, &spec);
      heap_dequeue(heap_p, less_than);
      printf("timeout = %d, run time is %ld\n", node_p->value, time(NULL)-last_time);
      last_time = time(NULL);
  }

  printf("timer is over!\n");

  return 0;
}

run the code ,you'll get

timeout = 2000, run time is 2
timeout = 3000, run time is 3
timeout = 4000, run time is 4
timeout = 5000, run time is 5
timeout = 6000, run time is 6
timeout = 7000, run time is 7
timeout = 8000, run time is 8
timeout = 9000, run time is 9
timeout = 10000, run time is 10
timer is over!

exactly as we expected!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions