compiles on macosx

This commit is contained in:
Yecheng Fu
2012-11-27 20:07:50 +08:00
parent b6314b537f
commit 8f29655d25
6 changed files with 232 additions and 28 deletions

View File

@@ -1,8 +1,15 @@
.PHONY : all clean
CFLAGS = -g -Wall
SHARED = -fPIC --shared
LUALIB = -llua
LDFLAGS = -lpthread -llua -ldl -lm
uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
ifeq ($(uname_S), Darwin)
SHARED = -fPIC -dynamiclib -Wl,-undefined,dynamic_lookup
else
LDFLAGS += -ldl -lrt -Wl,-E
SHARED = -fPIC --shared
endif
all : \
skynet \
@@ -37,7 +44,7 @@ skynet : \
skynet-src/skynet_env.c \
skynet-src/skynet_monitor.c \
luacompat/compat52.c
gcc $(CFLAGS) -Iluacompat -Wl,-E -o $@ $^ -Iskynet-src -lpthread -ldl -lrt -Wl,-E $(LUALIB) -lm
gcc $(CFLAGS) -Iluacompat -o $@ $^ -Iskynet-src $(LDFLAGS)
luaclib:
mkdir luaclib
@@ -89,4 +96,4 @@ client : client-src/client.c
clean :
rm skynet client service/*.so luaclib/*.so

View File

@@ -1,28 +1,67 @@
#include "connection.h"
#include <stdio.h>
#include <sys/epoll.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
/* Test for polling API */
#ifdef __linux__
#define HAVE_EPOLL 1
#endif
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined (__NetBSD__)
#define HAVE_KQUEUE 1
#endif
#if !defined(HAVE_EPOLL) && !defined(HAVE_KQUEUE)
#error "system does not support epoll or kqueue API"
#endif
/* ! Test for polling API */
#ifdef HAVE_EPOLL
#include <sys/epoll.h>
#elif HAVE_KQUEUE
#include <sys/event.h>
#endif
#define EPOLLQUEUE 32
struct connection_pool {
#ifdef HAVE_EPOLL
int epoll_fd;
#elif HAVE_KQUEUE
int kqueue_fd;
#endif
int queue_len;
int queue_head;
#ifdef HAVE_EPOLL
struct epoll_event ev[EPOLLQUEUE];
#elif HAVE_KQUEUE
struct kevent ev[EPOLLQUEUE];
#endif
};
struct connection_pool *
connection_newpool(int max) {
#ifdef HAVE_EPOLL
int epoll_fd = epoll_create(max);
if (epoll_fd == -1) {
return NULL;
}
#elif HAVE_KQUEUE
int kqueue_fd = kqueue();
if (kqueue_fd == -1) {
return NULL;
}
#endif
struct connection_pool * pool = malloc(sizeof(*pool));
#ifdef HAVE_EPOLL
pool->epoll_fd = epoll_fd;
#elif HAVE_KQUEUE
pool->kqueue_fd = kqueue_fd;
#endif
pool->queue_len = 0;
pool->queue_head = 0;
@@ -31,12 +70,17 @@ connection_newpool(int max) {
void
connection_deletepool(struct connection_pool * pool) {
#if HAVE_EPOLL
close(pool->epoll_fd);
#elif HAVE_KQUEUE
close(pool->kqueue_fd);
#endif
free(pool);
}
int
connection_add(struct connection_pool * pool, int fd, void *ud) {
#if HAVE_EPOLL
struct epoll_event ev;
ev.events = EPOLLIN;
ev.data.ptr = ud;
@@ -44,19 +88,39 @@ connection_add(struct connection_pool * pool, int fd, void *ud) {
if (epoll_ctl(pool->epoll_fd, EPOLL_CTL_ADD, fd, &ev) == -1) {
return 1;
}
#elif HAVE_KQUEUE
struct kevent ke;
EV_SET(&ke, fd, EVFILT_READ, EV_ADD, 0, 0, ud);
if (kevent(pool->kqueue_fd, &ke, 1, NULL, 0, NULL) == -1) {
return 1;
}
#endif
return 0;
}
void
connection_del(struct connection_pool * pool, int fd) {
#if HAVE_EPOLL
epoll_ctl(pool->epoll_fd, EPOLL_CTL_DEL, fd , NULL);
#elif HAVE_KQUEUE
struct kevent ke;
EV_SET(&ke, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
kevent(pool->kqueue_fd, &ke, 1, NULL, 0, NULL);
#endif
close(fd);
}
static int
_read_queue(struct connection_pool * pool, int timeout) {
pool->queue_head = 0;
#if HAVE_EPOLL
int n = epoll_wait(pool->epoll_fd , pool->ev, EPOLLQUEUE, timeout);
#elif HAVE_KQUEUE
struct timespec timeoutspec;
timeoutspec.tv_sec = timeout;
timeoutspec.tv_nsec = 0;
int n = kevent(pool->kqueue_fd, NULL, 0, pool->ev, EPOLLQUEUE, &timeoutspec);
#endif
if (n == -1) {
pool->queue_len = 0;
return -1;
@@ -72,6 +136,10 @@ connection_poll(struct connection_pool * pool, int timeout) {
return NULL;
}
}
#if HAVE_EPOLL
return pool->ev[pool->queue_head ++].data.ptr;
#elif HAVE_KQUEUE
return pool->ev[pool->queue_head ++].udata;
#endif
}

View File

@@ -1,7 +1,26 @@
#include "mread.h"
#include "ringbuffer.h"
/* Test for polling API */
#ifdef __linux__
#define HAVE_EPOLL 1
#endif
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined (__NetBSD__)
#define HAVE_KQUEUE 1
#endif
#if !defined(HAVE_EPOLL) && !defined(HAVE_KQUEUE)
#error "system does not support epoll or kqueue API"
#endif
/* ! Test for polling API */
#ifdef HAVE_EPOLL
#include <sys/epoll.h>
#elif HAVE_KQUEUE
#include <sys/event.h>
#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
@@ -38,7 +57,11 @@ struct socket {
struct mread_pool {
int listen_fd;
#ifdef HAVE_EPOLL
int epoll_fd;
#elif HAVE_KQUEUE
int kqueue_fd;
#endif
int max_connection;
int closed;
int active;
@@ -47,7 +70,11 @@ struct mread_pool {
struct socket * free_socket;
int queue_len;
int queue_head;
#ifdef HAVE_EPOLL
struct epoll_event ev[READQUEUE];
#elif HAVE_KQUEUE
struct kevent ev[READQUEUE];
#endif
struct ringbuffer * rb;
};
@@ -84,12 +111,12 @@ _release_rb(struct ringbuffer * rb) {
static int
_set_nonblocking(int fd)
{
int flag = fcntl(fd, F_GETFL, 0);
if ( -1 == flag ) {
return -1;
}
int flag = fcntl(fd, F_GETFL, 0);
if ( -1 == flag ) {
return -1;
}
return fcntl(fd, F_SETFL, flag | O_NONBLOCK);
return fcntl(fd, F_SETFL, flag | O_NONBLOCK);
}
struct mread_pool *
@@ -120,6 +147,7 @@ mread_create(uint32_t addr, int port , int max , int buffer_size) {
return NULL;
}
#ifdef HAVE_EPOLL
int epoll_fd = epoll_create(max + 1);
if (epoll_fd == -1) {
close(listen_fd);
@@ -135,11 +163,30 @@ mread_create(uint32_t addr, int port , int max , int buffer_size) {
close(epoll_fd);
return NULL;
}
#elif HAVE_KQUEUE
int kqueue_fd = kqueue();
if (kqueue_fd == -1) {
close(listen_fd);
return NULL;
}
struct kevent ke;
EV_SET(&ke, listen_fd, EVFILT_READ, EV_ADD, 0, 0, LISTENSOCKET);
if (kevent(kqueue_fd, &ke, 1, NULL, 0, NULL) == -1) {
close(listen_fd);
close(kqueue_fd);
return NULL;
}
#endif
struct mread_pool * self = malloc(sizeof(*self));
self->listen_fd = listen_fd;
#ifdef HAVE_EPOLL
self->epoll_fd = epoll_fd;
#elif HAVE_KQUEUE
self->kqueue_fd = kqueue_fd;
#endif
self->max_connection = max;
self->closed = 0;
self->active = -1;
@@ -172,7 +219,11 @@ mread_close(struct mread_pool *self) {
if (self->listen_fd >= 0) {
close(self->listen_fd);
}
close(self->epoll_fd);
#ifdef HAVE_EPOLL
close(self->epoll_fd);
#elif HAVE_KQUEUE
close(self->kqueue_fd);
#endif
_release_rb(self->rb);
free(self);
}
@@ -180,7 +231,14 @@ mread_close(struct mread_pool *self) {
static int
_read_queue(struct mread_pool * self, int timeout) {
self->queue_head = 0;
#ifdef HAVE_EPOLL
int n = epoll_wait(self->epoll_fd , self->ev, READQUEUE, timeout);
#elif HAVE_KQUEUE
struct timespec timeoutspec;
timeoutspec.tv_sec = timeout;
timeoutspec.tv_nsec = 0;
int n = kevent(self->kqueue_fd, NULL, 0, self->ev, READQUEUE, &timeoutspec);
#endif
if (n == -1) {
self->queue_len = 0;
return -1;
@@ -194,7 +252,11 @@ _read_one(struct mread_pool * self) {
if (self->queue_head >= self->queue_len) {
return NULL;
}
#ifdef HAVE_EPOLL
return self->ev[self->queue_head ++].data.ptr;
#elif HAVE_KQUEUE
return self->ev[self->queue_head ++].udata;
#endif
}
static struct socket *
@@ -219,6 +281,7 @@ _add_client(struct mread_pool * self, int fd) {
close(fd);
return NULL;
}
#ifdef HAVE_EPOLL
struct epoll_event ev;
ev.events = EPOLLIN;
ev.data.ptr = s;
@@ -226,6 +289,14 @@ _add_client(struct mread_pool * self, int fd) {
close(fd);
return NULL;
}
#elif HAVE_KQUEUE
struct kevent ke;
EV_SET(&ke, fd, EVFILT_READ, EV_ADD, 0, 0, s);
if (kevent(self->kqueue_fd, &ke, 1, NULL, 0, NULL) == -1) {
close(fd);
return NULL;
}
#endif
s->fd = fd;
s->node = NULL;
@@ -276,7 +347,7 @@ mread_poll(struct mread_pool * self , int timeout) {
socklen_t len = sizeof(struct sockaddr_in);
int client_fd = accept(self->listen_fd , (struct sockaddr *)&remote_addr , &len);
if (client_fd >= 0) {
// printf("MREAD(%p) connect %s:%u (fd=%d)\n",self, inet_ntoa(remote_addr.sin_addr),ntohs(remote_addr.sin_port), client_fd);
// printf("MREAD connect %s:%u (fd=%d)\n",inet_ntoa(remote_addr.sin_addr),ntohs(remote_addr.sin_port), client_fd);
struct socket * s = _add_client(self, client_fd);
if (s) {
self->active = -1;
@@ -301,7 +372,7 @@ mread_socket(struct mread_pool * self, int index) {
static void
_link_node(struct ringbuffer * rb, int id, struct socket * s , struct ringbuffer_block * blk) {
if (s->node) {
ringbuffer_link(rb, s->node , blk);
ringbuffer_link(rb, s->node , blk);
} else {
blk->id = id;
s->node = blk;
@@ -316,7 +387,14 @@ mread_close_client(struct mread_pool * self, int id) {
s->temp = NULL;
close(s->fd);
// printf("MREAD close %d (fd=%d)\n",id,s->fd);
#ifdef HAVE_EPOLL
epoll_ctl(self->epoll_fd, EPOLL_CTL_DEL, s->fd , NULL);
#elif HAVE_KQUEUE
struct kevent ke;
EV_SET(&ke, s->fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
kevent(self->kqueue_fd, &ke, 1, NULL, 0, NULL);
#endif
++self->closed;
}
@@ -343,7 +421,7 @@ _ringbuffer_read(struct mread_pool * self, int *size) {
return ret;
}
void *
void *
mread_pull(struct mread_pool * self , int size) {
if (self->active == -1) {
return NULL;
@@ -388,16 +466,8 @@ mread_pull(struct mread_pool * self , int size) {
buffer = (char *)(blk + 1);
for (;;) {
int bytes = recv(s->fd, buffer, rd, MSG_DONTWAIT);
int bytes = recv(s->fd, buffer, rd, MSG_DONTWAIT);
if (bytes > 0) {
/*
printf("recv: [%d] ",s->fd);
int i;
for (i=0;i<bytes;i++) {
printf("%02x ",(uint8_t*)buffer[i]);
}
printf("\n");
*/
ringbuffer_shrink(rb, blk , bytes);
if (bytes < sz) {
_link_node(rb, self->active, s , blk);
@@ -456,7 +526,7 @@ mread_pull(struct mread_pool * self , int size) {
return ret;
}
void
void
mread_yield(struct mread_pool * self) {
if (self->active == -1) {
return;
@@ -482,7 +552,7 @@ mread_yield(struct mread_pool * self) {
}
}
int
int
mread_closed(struct mread_pool * self) {
if (self->active == -1) {
return 0;

View File

@@ -15,6 +15,11 @@
#include <assert.h>
#include <time.h>
#if defined(__APPLE__)
#include <mach/task.h>
#include <mach/mach.h>
#endif
struct stat {
lua_State *L;
int count;
@@ -27,7 +32,15 @@ struct stat {
static void
_stat_begin(struct stat *S, struct timespec *ti) {
S->count++;
#if defined(_POSIX_TIMERS) && defined(_POSIX_THREAD_CPUTIME)
clock_gettime(CLOCK_THREAD_CPUTIME_ID, ti);
#elif defined(__APPLE__)
struct task_thread_times_info aTaskInfo;
mach_msg_type_number_t aTaskInfoCount = TASK_THREAD_TIMES_INFO_COUNT;
assert(KERN_SUCCESS == task_info(mach_task_self(), TASK_THREAD_TIMES_INFO, (task_info_t )&aTaskInfo, &aTaskInfoCount));
ti->tv_sec = aTaskInfo.user_time.seconds;
ti->tv_nsec = aTaskInfo.user_time.microseconds * 1000;
#endif
}
inline static void

View File

@@ -8,10 +8,23 @@
#define HASH_SIZE 32
#if defined(__APPLE__)
#include <mach/task.h>
#include <mach/mach.h>
#endif
void
diff_time(struct timespec *ti, uint32_t *sec, uint32_t *nsec) {
struct timespec end;
#if defined(_POSIX_TIMERS) && defined(_POSIX_THREAD_CPUTIME)
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end);
#elif defined(__APPLE__)
struct task_thread_times_info aTaskInfo;
mach_msg_type_number_t aTaskInfoCount = TASK_THREAD_TIMES_INFO_COUNT;
assert(KERN_SUCCESS == task_info(mach_task_self(), TASK_THREAD_TIMES_INFO, (task_info_t )&aTaskInfo, &aTaskInfoCount));
end.tv_sec = aTaskInfo.user_time.seconds;
end.tv_nsec = aTaskInfo.user_time.microseconds * 1000;
#endif
int diffsec = end.tv_sec - ti->tv_sec;
assert(diffsec>=0);
int diffnsec = end.tv_nsec - ti->tv_nsec;
@@ -76,7 +89,15 @@ trace_new(struct trace_pool *p) {
t->next = NULL;
t->ti_sec = 0;
t->ti_nsec = 0;
#if defined(_POSIX_TIMERS) && defined(_POSIX_THREAD_CPUTIME)
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t->ti);
#elif defined(__APPLE__)
struct task_thread_times_info aTaskInfo;
mach_msg_type_number_t aTaskInfoCount = TASK_THREAD_TIMES_INFO_COUNT;
assert(KERN_SUCCESS == task_info(mach_task_self(), TASK_THREAD_TIMES_INFO, (task_info_t )&aTaskInfo, &aTaskInfoCount));
t->ti.tv_sec = aTaskInfo.user_time.seconds;
t->ti.tv_nsec = aTaskInfo.user_time.microseconds * 1000;
#endif
return t;
}
@@ -130,7 +151,15 @@ trace_switch(struct trace_pool *p, int session) {
if (t->next) {
t->next->prev = prev;
}
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t->ti);
#if defined(_POSIX_TIMERS) && defined(_POSIX_THREAD_CPUTIME)
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t->ti);
#elif defined(__APPLE__)
struct task_thread_times_info aTaskInfo;
mach_msg_type_number_t aTaskInfoCount = TASK_THREAD_TIMES_INFO_COUNT;
assert(KERN_SUCCESS == task_info(mach_task_self(), TASK_THREAD_TIMES_INFO, (task_info_t )&aTaskInfo, &aTaskInfoCount));
t->ti.tv_sec = aTaskInfo.user_time.seconds;
t->ti.tv_nsec = aTaskInfo.user_time.microseconds * 1000;
#endif
return;
}
prev = t;

View File

@@ -9,6 +9,10 @@
#include <string.h>
#include <stdlib.h>
#if !defined(_POSIX_TIMERS)
#include <sys/time.h>
#endif
typedef void (*timer_execute_func)(void *ud,void *arg);
#define TIME_NEAR_SHIFT 8
@@ -198,11 +202,18 @@ skynet_timeout(uint32_t handle, int time, int session) {
static uint32_t
_gettime(void) {
uint32_t t;
#if defined(_POSIX_TIMERS)
struct timespec ti;
clock_gettime(CLOCK_MONOTONIC, &ti);
uint32_t t = (uint32_t)(ti.tv_sec & 0xffffff) * 100;
t = (uint32_t)(ti.tv_sec & 0xffffff) * 100;
t += ti.tv_nsec / 10000000;
#else
struct timeval tv;
gettimeofday(&tv, NULL);
t = (uint32_t)(tv.tv_sec & 0xffffff) * 100;
t += tv.tv_usec / 10000;
#endif
return t;
}
@@ -234,9 +245,15 @@ skynet_timer_init(void) {
TI = timer_create_timer();
TI->current = _gettime();
#if defined(_POSIX_TIMERS)
struct timespec ti;
clock_gettime(CLOCK_REALTIME, &ti);
uint32_t sec = (uint32_t)ti.tv_sec;
#else
struct timeval tv;
gettimeofday(&tv, NULL);
uint32_t sec = (uint32_t)tv.tv_sec;
#endif
uint32_t mono = _gettime() / 100;
TI->starttime = sec - mono;