mirror of https://github.com/F-Stack/f-stack.git
Add adapter for LD_PRELOAD, TBC.
This commit is contained in:
parent
c0cab32e5f
commit
865ab0ed63
|
@ -0,0 +1,75 @@
|
|||
TOPDIR=..
|
||||
|
||||
ifeq ($(FF_PATH),)
|
||||
FF_PATH=${TOPDIR}
|
||||
endif
|
||||
|
||||
ifneq ($(shell pkg-config --exists libdpdk && echo 0),0)
|
||||
$(error "No installation of DPDK found, maybe you should export environment variable `PKG_CONFIG_PATH`")
|
||||
endif
|
||||
|
||||
DEBUG=-O0 -gdwarf-2 -g3 -DDEBUG
|
||||
|
||||
PKGCONF ?= pkg-config
|
||||
|
||||
ifndef DEBUG
|
||||
CFLAGS+= -g -O2
|
||||
else
|
||||
CFLAGS+= ${DEBUG}
|
||||
endif
|
||||
CFLAGS += -fPIC -Wall -Werror $(shell $(PKGCONF) --cflags libdpdk)
|
||||
|
||||
INCLUDES= -I. -I${FF_PATH}/lib
|
||||
|
||||
FF_LIBS= -L${FF_PATH}/lib -Wl,--whole-archive,-lfstack,--no-whole-archive
|
||||
|
||||
DPDK_LIBS+= $(shell $(PKGCONF) --static --libs libdpdk)
|
||||
DPDK_LIBS+= -Wl,--no-whole-archive -lrt -lm -ldl -lcrypto -pthread -lnuma
|
||||
|
||||
#DPDK_CFLAGS= -Wall -Werror -include ${FF_DPDK}/include/rte_config.h
|
||||
#DPDK_CFLAGS+= -march=native -DRTE_MACHINE_CPUFLAG_SSE -DRTE_MACHINE_CPUFLAG_SSE2 -DRTE_MACHINE_CPUFLAG_SSE3
|
||||
#DPDK_CFLAGS+= -DRTE_MACHINE_CPUFLAG_SSSE3 -DRTE_MACHINE_CPUFLAG_SSE4_1 -DRTE_MACHINE_CPUFLAG_SSE4_2
|
||||
#DPDK_CFLAGS+= -DRTE_COMPILE_TIME_CPUFLAGS=RTE_CPUFLAG_SSE,RTE_CPUFLAG_SSE2,RTE_CPUFLAG_SSE3,RTE_CPUFLAG_SSSE3,RTE_CPUFLAG_SSE4_1,RTE_CPUFLAG_SSE4_2
|
||||
#DPDK_CFLAGS+= -I${FF_DPDK}/include
|
||||
|
||||
CFLAGS+= ${INCLUDES} ${DPDK_CFLAGS}
|
||||
|
||||
FSTACK_LIBS= ${FF_LIBS} ${DPDK_LIBS}
|
||||
FF_SYSCALL_LIBS=
|
||||
|
||||
FSTACK_SRCS= \
|
||||
fstack.c \
|
||||
ff_so_zone.c \
|
||||
ff_socket_ops.c
|
||||
|
||||
FF_SYSCALL_SRCS= \
|
||||
ff_so_zone.c \
|
||||
ff_hook_syscall.c \
|
||||
ff_linux_syscall.c
|
||||
|
||||
FSTACK_OBJS= $(patsubst %.c,%.o,${FSTACK_SRCS})
|
||||
|
||||
FF_SYSCALL_OBJS= $(patsubst %.c,%.o,${FF_SYSCALL_SRCS})
|
||||
|
||||
#TARGET= fstack libff_syscall.a
|
||||
TARGET= fstack libff_syscall.so
|
||||
|
||||
all: ${TARGET}
|
||||
|
||||
fstack: ${FSTACK_OBJS}
|
||||
cc -o $@ $^ ${FSTACK_LIBS}
|
||||
|
||||
#libff_syscall.a: ${FF_SYSCALL_OBJS}
|
||||
libff_syscall.so: ${FF_SYSCALL_OBJS}
|
||||
#ar -rcs $@ $^ ${FF_SYSCALL_LIBS}
|
||||
${CC} -fPIC -shared -o $@ $^ ${FF_SYSCALL_LIBS}
|
||||
|
||||
${FSTACK_OBJS}: %.o: %.c
|
||||
${CC} -c $(CFLAGS) ${PROF} $<
|
||||
|
||||
${FF_SYSCALL_OBJS}: %.o: %.c
|
||||
${CC} -c $(CFLAGS) ${PROF} $<
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f *.o ${TARGET}
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef _FF_ADAPTER_H
|
||||
#define _FF_ADAPTER_H
|
||||
|
||||
/* socket.h */
|
||||
//#define SOCK_CLOEXEC 0x10000000
|
||||
//#define SOCK_NONBLOCK 0x20000000
|
||||
#define SOCK_FSTACK 0x01000000
|
||||
#define SOCK_KERNEL 0x02000000
|
||||
|
||||
int ff_adapter_init();
|
||||
//int __attribute__((constructor)) ff_adapter_init(int argc, char * const argv[]);
|
||||
|
||||
/*-
|
||||
* Verify whether the socket is supported by fstack or not.
|
||||
*/
|
||||
int fstack_territory(int domain, int type, int protocol);
|
||||
|
||||
/* Tell whether a 'sockfd' belongs to fstack. */
|
||||
int is_fstack_fd(int fd);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,31 @@
|
|||
FF_SYSCALL_DECL(int, socket, (int, int, int));
|
||||
FF_SYSCALL_DECL(int, bind, (int, const struct sockaddr *, socklen_t));
|
||||
FF_SYSCALL_DECL(int, listen, (int, int));
|
||||
FF_SYSCALL_DECL(int, shutdown, (int, int));
|
||||
FF_SYSCALL_DECL(int, getsockname, (int, struct sockaddr *, socklen_t *));
|
||||
FF_SYSCALL_DECL(int, getpeername, (int, struct sockaddr *, socklen_t *));
|
||||
FF_SYSCALL_DECL(int, getsockopt, (int, int, int, void *, socklen_t *));
|
||||
FF_SYSCALL_DECL(int, setsockopt, (int, int, int, const void *, socklen_t));
|
||||
FF_SYSCALL_DECL(int, accept, (int, struct sockaddr *, socklen_t *));
|
||||
FF_SYSCALL_DECL(int, accept4,(int, struct sockaddr *, socklen_t *, int flags));
|
||||
FF_SYSCALL_DECL(int, connect, (int, const struct sockaddr *, socklen_t));
|
||||
FF_SYSCALL_DECL(ssize_t, recv, (int, void *, size_t, int));
|
||||
FF_SYSCALL_DECL(ssize_t, send, (int, const void *, size_t, int));
|
||||
FF_SYSCALL_DECL(ssize_t, read, (int, void *, size_t));
|
||||
FF_SYSCALL_DECL(ssize_t, write, (int, const void *, size_t));
|
||||
FF_SYSCALL_DECL(ssize_t, writev, (int, const struct iovec *, int));
|
||||
FF_SYSCALL_DECL(ssize_t, readv, (int, const struct iovec *, int));
|
||||
FF_SYSCALL_DECL(ssize_t, sendto, (int, const void *, size_t, int,
|
||||
const struct sockaddr *, socklen_t));
|
||||
FF_SYSCALL_DECL(ssize_t, recvfrom, (int, void *, size_t, int,
|
||||
struct sockaddr *, socklen_t *));
|
||||
FF_SYSCALL_DECL(ssize_t, sendmsg, (int, const struct msghdr *, int flags));
|
||||
FF_SYSCALL_DECL(ssize_t, recvmsg, (int, struct msghdr *, int flags));
|
||||
FF_SYSCALL_DECL(int, close, (int));
|
||||
FF_SYSCALL_DECL(int, ioctl, (int, unsigned long, unsigned long));
|
||||
FF_SYSCALL_DECL(int, fcntl, (int, int, unsigned long));
|
||||
FF_SYSCALL_DECL(int, epoll_create, (int));
|
||||
FF_SYSCALL_DECL(int, epoll_ctl, (int, int, int, struct epoll_event *));
|
||||
FF_SYSCALL_DECL(int, epoll_wait, (int, struct epoll_event *, int, int));
|
||||
FF_SYSCALL_DECL(pid_t, fork, (void));
|
||||
#undef FF_SYSCALL_DECL
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,8 @@
|
|||
#ifndef _FF_HOOK_SYSCALL_H
|
||||
#define _FF_HOOK_SYSCALL_H
|
||||
|
||||
#undef FF_SYSCALL_DECL
|
||||
#define FF_SYSCALL_DECL(ret, fn, args) extern ret ff_hook_##fn args
|
||||
#include <ff_declare_syscalls.h>
|
||||
|
||||
#endif
|
|
@ -0,0 +1,236 @@
|
|||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "ff_socket_ops.h"
|
||||
#include "ff_linux_syscall.h"
|
||||
|
||||
#define SYSCALL(symbol, para) { \
|
||||
if (linux_syscall_inited == 0) { \
|
||||
if (linux_syscall_init() != 0) { \
|
||||
return -1; \
|
||||
} \
|
||||
} \
|
||||
if (syscalls.pf_##symbol) { \
|
||||
return syscalls.pf_##symbol para; \
|
||||
} \
|
||||
errno = ENOSYS; \
|
||||
return -1; \
|
||||
}
|
||||
|
||||
struct ff_linux_syscall {
|
||||
#define FF_SYSCALL_DECL(ret, fn, args) ret (*pf_##fn) args;
|
||||
#include "ff_declare_syscalls.h"
|
||||
};
|
||||
|
||||
static int linux_syscall_inited;
|
||||
|
||||
static struct ff_linux_syscall syscalls = { 0 };
|
||||
|
||||
static void *linux_lib_handle = NULL;
|
||||
|
||||
pthread_mutex_t syscall_init_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static inline int
|
||||
linux_syscall_load_symbol()
|
||||
{
|
||||
linux_lib_handle = dlopen ("libc.so.6", RTLD_NOW | RTLD_GLOBAL);
|
||||
if (linux_lib_handle == NULL) {
|
||||
ERR_LOG("cannot dlopen libc.so.6] err_string=%s", dlerror());
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define FF_SYSCALL_DECL(ret, fn, args) \
|
||||
syscalls.pf_##fn = (typeof(syscalls.pf_##fn))dlsym(linux_lib_handle, #fn);
|
||||
#include <ff_declare_syscalls.h>
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
linux_syscall_init()
|
||||
{
|
||||
if (linux_syscall_inited) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&syscall_init_mutex);
|
||||
if (linux_syscall_inited) {
|
||||
pthread_mutex_unlock(&syscall_init_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (linux_syscall_load_symbol() != 0) {
|
||||
pthread_mutex_unlock(&syscall_init_mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
linux_syscall_inited = 1;
|
||||
|
||||
pthread_mutex_unlock(&syscall_init_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ff_linux_socket(int domain, int type, int protocol)
|
||||
{
|
||||
DEBUG_LOG("ff_linux_socket, domain:%d, type:%d, protocol:%d\n", domain, type, protocol);
|
||||
SYSCALL(socket, (domain, type, protocol));
|
||||
}
|
||||
|
||||
int
|
||||
ff_linux_bind(int s, const struct sockaddr *addr,
|
||||
socklen_t addrlen)
|
||||
{
|
||||
SYSCALL(bind, (s, addr, addrlen));
|
||||
}
|
||||
|
||||
int
|
||||
ff_linux_listen(int s, int backlog)
|
||||
{
|
||||
SYSCALL(listen, (s, backlog));
|
||||
}
|
||||
|
||||
int ff_linux_shutdown(int s, int how)
|
||||
{
|
||||
SYSCALL(shutdown, (s, how));
|
||||
}
|
||||
|
||||
int ff_linux_getsockname(int s, struct sockaddr *name,
|
||||
socklen_t *namelen)
|
||||
{
|
||||
SYSCALL(getsockname, (s, name, namelen));
|
||||
}
|
||||
|
||||
int ff_linux_getpeername(int s, struct sockaddr *name,
|
||||
socklen_t *namelen)
|
||||
{
|
||||
SYSCALL(getpeername, (s, name, namelen));
|
||||
}
|
||||
|
||||
int ff_linux_getsockopt(int s, int level, int optname,
|
||||
void *optval, socklen_t *optlen)
|
||||
{
|
||||
SYSCALL(getsockopt, (s, level, optname, optval, optlen));
|
||||
}
|
||||
|
||||
int ff_linux_setsockopt(int s, int level, int optname,
|
||||
const void *optval, socklen_t optlen)
|
||||
{
|
||||
SYSCALL(setsockopt, (s, level, optname, optval, optlen));
|
||||
}
|
||||
|
||||
int ff_linux_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
|
||||
{
|
||||
SYSCALL(accept, (s, addr, addrlen));
|
||||
}
|
||||
|
||||
int ff_linux_accept4(int s, struct sockaddr *addr,
|
||||
socklen_t *addrlen, int flags)
|
||||
{
|
||||
SYSCALL(accept4, (s, addr, addrlen, flags));
|
||||
}
|
||||
|
||||
int ff_linux_connect(int s, const struct sockaddr *addr,
|
||||
socklen_t addrlen)
|
||||
{
|
||||
SYSCALL(connect, (s, addr, addrlen));
|
||||
}
|
||||
|
||||
ssize_t ff_linux_recv(int s, void *buf, size_t len, int flags)
|
||||
{
|
||||
SYSCALL(recv, (s, buf, len, flags));
|
||||
}
|
||||
|
||||
ssize_t ff_linux_send(int s, const void *buf, size_t len, int flags)
|
||||
{
|
||||
SYSCALL(send, (s, buf, len, flags));
|
||||
}
|
||||
|
||||
ssize_t ff_linux_read(int s, void *buf, size_t len)
|
||||
{
|
||||
SYSCALL(read, (s, buf, len));
|
||||
}
|
||||
|
||||
ssize_t ff_linux_write(int s, const void *buf, size_t len)
|
||||
{
|
||||
SYSCALL(write, (s, buf, len));
|
||||
}
|
||||
|
||||
ssize_t ff_linux_writev(int s, const struct iovec *iov, int iovcnt)
|
||||
{
|
||||
SYSCALL(writev, (s, iov, iovcnt));
|
||||
}
|
||||
|
||||
ssize_t ff_linux_readv(int s, const struct iovec *iov, int iovcnt)
|
||||
{
|
||||
SYSCALL(readv, (s, iov, iovcnt));
|
||||
}
|
||||
|
||||
ssize_t ff_linux_sendto(int s, const void *buf, size_t len, int flags,
|
||||
const struct sockaddr *to, socklen_t tolen)
|
||||
{
|
||||
SYSCALL(sendto, (s, buf, len, flags, to, tolen));
|
||||
}
|
||||
|
||||
ssize_t ff_linux_recvfrom(int s, void *buf, size_t len, int flags,
|
||||
struct sockaddr *from, socklen_t *fromlen)
|
||||
|
||||
{
|
||||
SYSCALL(recvfrom, (s, buf, len, flags, from, fromlen));
|
||||
}
|
||||
|
||||
ssize_t ff_linux_sendmsg(int s, const struct msghdr *msg, int flags)
|
||||
{
|
||||
SYSCALL(sendmsg, (s, msg, flags));
|
||||
}
|
||||
|
||||
ssize_t ff_linux_recvmsg(int s, struct msghdr *msg, int flags)
|
||||
{
|
||||
SYSCALL(recvmsg, (s, msg, flags))
|
||||
}
|
||||
|
||||
int ff_linux_close(int s)
|
||||
{
|
||||
SYSCALL(close, (s));
|
||||
}
|
||||
|
||||
int ff_linux_ioctl(int s, unsigned long req, unsigned long data)
|
||||
{
|
||||
SYSCALL(ioctl, (s, req, data));
|
||||
}
|
||||
|
||||
int ff_linux_fcntl(int s, int cmd, unsigned long data)
|
||||
{
|
||||
SYSCALL(fcntl, (s, cmd, data));
|
||||
}
|
||||
|
||||
int ff_linux_epoll_create(int size)
|
||||
{
|
||||
DEBUG_LOG("ff_linux_epoll_create, fdsize:%d\n", size);
|
||||
SYSCALL(epoll_create, (size));
|
||||
}
|
||||
|
||||
int ff_linux_epoll_ctl(int epfd, int op, int fd,
|
||||
struct epoll_event *event)
|
||||
{
|
||||
DEBUG_LOG("ff_linux_epoll_ctl, epfd:%d, op:%d, fd:%d\n", epfd, op, fd);
|
||||
SYSCALL(epoll_ctl, (epfd, op, fd, event));
|
||||
}
|
||||
|
||||
int
|
||||
ff_linux_epoll_wait(int epfd, struct epoll_event *events,
|
||||
int maxevents, int timeout)
|
||||
{
|
||||
DEBUG_LOG("ff_linux_epoll_wait, epfd:%d, maxevents:%d, timeout:%d\n", epfd, maxevents, timeout);
|
||||
SYSCALL(epoll_wait, (epfd, events, maxevents, timeout));
|
||||
}
|
||||
|
||||
pid_t
|
||||
ff_linux_fork(void)
|
||||
{
|
||||
SYSCALL(fork, ());
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef _FF_LINUX_SYSCALL_H_
|
||||
#define _FF_LINUX_SYSCALL_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#undef FF_SYSCALL_DECL
|
||||
#define FF_SYSCALL_DECL(ret, fn, args) ret ff_linux_##fn args
|
||||
#include "ff_declare_syscalls.h"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,170 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <rte_eal.h>
|
||||
#include <rte_memzone.h>
|
||||
|
||||
#include "ff_config.h"
|
||||
#include "ff_socket_ops.h"
|
||||
|
||||
#define SOCKET_OPS_ZONE_NAME "ff_socket_ops_zone_%d"
|
||||
|
||||
#define SOCKET_OPS_CONTEXT_MAX_NUM 32
|
||||
|
||||
#define SOCKET_OPS_CONTEXT_NAME_SIZE 32
|
||||
#define SOCKET_OPS_CONTEXT_NAME "ff_so_context_"
|
||||
|
||||
static uint16_t ff_max_so_context = SOCKET_OPS_CONTEXT_MAX_NUM;
|
||||
struct ff_socket_ops_zone *ff_so_zone;
|
||||
|
||||
int
|
||||
ff_set_max_so_context(uint16_t count)
|
||||
{
|
||||
if (ff_so_zone) {
|
||||
ERR_LOG("Can not set: memzone has inited\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
|
||||
ERR_LOG("Can not set: process is not primary\n");
|
||||
return 1;
|
||||
}*/
|
||||
|
||||
ff_max_so_context = count;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ff_create_so_memzone()
|
||||
{
|
||||
if (ff_so_zone) {
|
||||
ERR_LOG("Can not create memzone: memzone has inited\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
|
||||
uint16_t i, proc_id;
|
||||
for (proc_id = 0; proc_id < ff_global_cfg.dpdk.nb_procs; proc_id++) {
|
||||
struct ff_socket_ops_zone *so_zone_tmp;
|
||||
const struct rte_memzone *mz;
|
||||
char zn[64];
|
||||
|
||||
size_t zone_size = sizeof(struct ff_socket_ops_zone) +
|
||||
sizeof(struct ff_so_context) * ff_max_so_context;
|
||||
snprintf(zn, sizeof(zn), SOCKET_OPS_ZONE_NAME, proc_id);
|
||||
ERR_LOG("To create memzone:%s\n", zn);
|
||||
|
||||
mz = rte_memzone_reserve(zn, zone_size, rte_socket_id(), 0);
|
||||
if (mz == NULL) {
|
||||
ERR_LOG("Cannot reserve memory zone:%s\n", zn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(mz->addr, 0, zone_size);
|
||||
so_zone_tmp = mz->addr;
|
||||
|
||||
rte_spinlock_init(&so_zone_tmp->lock);
|
||||
so_zone_tmp->count = ff_max_so_context;
|
||||
so_zone_tmp->free = so_zone_tmp->count;
|
||||
so_zone_tmp->sc = (struct ff_so_context *)(so_zone_tmp + 1);
|
||||
|
||||
for (i = 0; i < ff_max_so_context; i++) {
|
||||
struct ff_so_context *sc = &so_zone_tmp->sc[i];
|
||||
rte_spinlock_init(&sc->lock);
|
||||
sc->status = FF_SC_IDLE;
|
||||
sc->inuse = 0;
|
||||
|
||||
if (sem_init(&sc->wait_sem, 1, 0) == -1) {
|
||||
ERR_LOG("Initialize semaphore failed:%d\n", errno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (proc_id == 0) {
|
||||
ff_so_zone = so_zone_tmp;
|
||||
}
|
||||
}
|
||||
}else {
|
||||
const struct rte_memzone *mz;
|
||||
char zn[64];
|
||||
|
||||
snprintf(zn, sizeof(zn), SOCKET_OPS_ZONE_NAME, ff_global_cfg.dpdk.proc_id);
|
||||
ERR_LOG("To lookup memzone:%s\n", zn);
|
||||
|
||||
mz = rte_memzone_lookup(zn);
|
||||
if (mz == NULL) {
|
||||
ERR_LOG("Lookup memory zone:%s failed\n", zn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ff_so_zone = mz->addr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ff_so_context *
|
||||
ff_attach_so_context(int proc_id)
|
||||
{
|
||||
struct ff_so_context *sc = NULL;
|
||||
uint16_t i;
|
||||
|
||||
if (ff_so_zone == NULL) {
|
||||
const struct rte_memzone *mz;
|
||||
char zn[64];
|
||||
|
||||
snprintf(zn, sizeof(zn), SOCKET_OPS_ZONE_NAME, proc_id);
|
||||
ERR_LOG("To lookup memzone:%s\n", zn);
|
||||
|
||||
mz = rte_memzone_lookup(zn);
|
||||
if (mz == NULL) {
|
||||
ERR_LOG("Lookup memory zone:%s failed\n", zn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ff_so_zone = mz->addr;
|
||||
}
|
||||
|
||||
rte_spinlock_lock(&ff_so_zone->lock);
|
||||
|
||||
if (ff_so_zone->free == 0) {
|
||||
ERR_LOG("Attach memzone failed: no free context\n");
|
||||
rte_spinlock_unlock(&ff_so_zone->lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* i从count-free开始尝试,直到一轮结束 */
|
||||
for (i = 0; i < ff_so_zone->count; i++) {
|
||||
sc = &ff_so_zone->sc[i];
|
||||
if (sc->inuse == 0) {
|
||||
sc->inuse = 1;
|
||||
rte_spinlock_init(&sc->lock);
|
||||
sc->status = FF_SC_IDLE;
|
||||
ff_so_zone->free--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
DEBUG_LOG("attach sc:%p, i:%d\n", sc, i);
|
||||
|
||||
rte_spinlock_unlock(&ff_so_zone->lock);
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
void
|
||||
ff_detach_so_context(struct ff_so_context *sc)
|
||||
{
|
||||
if (ff_so_zone == NULL || sc == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
rte_spinlock_lock(&ff_so_zone->lock);
|
||||
|
||||
sc->inuse = 0;
|
||||
|
||||
ff_so_zone->free++;
|
||||
DEBUG_LOG("detach sc:%p, status:%d, ops:%d\n", sc, sc->status, sc->ops);
|
||||
|
||||
rte_spinlock_unlock(&ff_so_zone->lock);
|
||||
}
|
|
@ -0,0 +1,461 @@
|
|||
#include <rte_memcpy.h>
|
||||
#include <rte_spinlock.h>
|
||||
|
||||
#include "ff_socket_ops.h"
|
||||
#include "ff_sysproto.h"
|
||||
#include "ff_api.h"
|
||||
#include "ff_epoll.h"
|
||||
|
||||
#undef FF_SYSCALL_DECL
|
||||
#define FF_SYSCALL_DECL(ret, fn, none) \
|
||||
static ret ff_sys_##fn(struct ff_##fn##_args *args);
|
||||
#include <ff_declare_syscalls.h>
|
||||
static int ff_sys_kqueue(struct ff_kqueue_args *args);
|
||||
static int ff_sys_kevent(struct ff_kevent_args *args);
|
||||
|
||||
extern struct ff_socket_ops_zone *ff_so_zone;
|
||||
|
||||
#define FF_MAX_BOUND_NUM 8
|
||||
|
||||
|
||||
struct ff_bound_info {
|
||||
int fd;
|
||||
struct sockaddr addr;
|
||||
};
|
||||
|
||||
static struct ff_bound_info ff_bound_fds[FF_MAX_BOUND_NUM];
|
||||
|
||||
static int
|
||||
sockaddr_cmp(struct sockaddr *a, struct sockaddr *b)
|
||||
{
|
||||
struct sockaddr_in *sina, *sinb;
|
||||
sina = (struct sockaddr_in *)a;
|
||||
sinb = (struct sockaddr_in *)b;
|
||||
|
||||
if (sina->sin_family != sinb->sin_family) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (sina->sin_port != sinb->sin_port) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (sina->sin_addr.s_addr != sinb->sin_addr.s_addr) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sockaddr_is_bound(struct sockaddr *addr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < FF_MAX_BOUND_NUM; i++) {
|
||||
struct ff_bound_info *info = &ff_bound_fds[i];
|
||||
if (info->fd == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sockaddr_cmp(&info->addr, addr) == 0) {
|
||||
return info->fd;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
sockaddr_bind(int fd, struct sockaddr *addr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < FF_MAX_BOUND_NUM; i++) {
|
||||
struct ff_bound_info *info = &ff_bound_fds[i];
|
||||
if (info->fd != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
info->fd = fd;
|
||||
rte_memcpy(&info->addr, addr, sizeof(struct sockaddr));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
sockaddr_unbind(int fd)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < FF_MAX_BOUND_NUM; i++) {
|
||||
struct ff_bound_info *info = &ff_bound_fds[i];
|
||||
if (info->fd != fd) {
|
||||
continue;
|
||||
}
|
||||
|
||||
info->fd = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
ff_sys_socket(struct ff_socket_args *args)
|
||||
{
|
||||
return ff_socket(args->domain, args->type, args->protocol);
|
||||
}
|
||||
|
||||
static int
|
||||
ff_sys_bind(struct ff_bind_args *args)
|
||||
{
|
||||
int bound_fd;
|
||||
int ret;
|
||||
|
||||
bound_fd = sockaddr_is_bound(args->addr);
|
||||
if (bound_fd != 0 && bound_fd != args->fd) {
|
||||
return ff_dup2(bound_fd, args->fd);
|
||||
}
|
||||
|
||||
ret = ff_bind(args->fd, args->addr, args->addrlen);
|
||||
if (ret == 0) {
|
||||
sockaddr_bind(args->fd, args->addr);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
ff_sys_listen(struct ff_listen_args *args)
|
||||
{
|
||||
return ff_listen(args->fd, args->backlog);
|
||||
}
|
||||
|
||||
static int
|
||||
ff_sys_shutdown(struct ff_shutdown_args *args)
|
||||
{
|
||||
return ff_shutdown(args->fd, args->how);
|
||||
}
|
||||
|
||||
static int
|
||||
ff_sys_getsockname(struct ff_getsockname_args *args)
|
||||
{
|
||||
return ff_getsockname(args->fd, args->name, args->namelen);
|
||||
}
|
||||
|
||||
static int
|
||||
ff_sys_getpeername(struct ff_getpeername_args *args)
|
||||
{
|
||||
return ff_getpeername(args->fd, args->name, args->namelen);
|
||||
}
|
||||
|
||||
static int
|
||||
ff_sys_getsockopt(struct ff_getsockopt_args *args)
|
||||
{
|
||||
return ff_getsockopt(args->fd, args->level, args->name,
|
||||
args->optval, args->optlen);
|
||||
}
|
||||
|
||||
static int
|
||||
ff_sys_setsockopt(struct ff_setsockopt_args *args)
|
||||
{
|
||||
return ff_setsockopt(args->fd, args->level, args->name,
|
||||
args->optval, args->optlen);
|
||||
}
|
||||
|
||||
static int
|
||||
ff_sys_accept(struct ff_accept_args *args)
|
||||
{
|
||||
return ff_accept(args->fd, args->addr, args->addrlen);
|
||||
}
|
||||
|
||||
static int
|
||||
ff_sys_accept4(struct ff_accept4_args *args)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
ff_sys_connect(struct ff_connect_args *args)
|
||||
{
|
||||
return ff_connect(args->fd, args->addr, args->addrlen);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
ff_sys_recv(struct ff_recv_args *args)
|
||||
{
|
||||
return ff_recv(args->fd, args->buf, args->len, args->flags);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
ff_sys_recvfrom(struct ff_recvfrom_args *args)
|
||||
{
|
||||
return ff_recvfrom(args->fd, args->buf, args->len, args->flags,
|
||||
args->from, args->fromlen);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
ff_sys_recvmsg(struct ff_recvmsg_args *args)
|
||||
{
|
||||
return ff_recvmsg(args->fd, args->msg, args->flags);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
ff_sys_read(struct ff_read_args *args)
|
||||
{
|
||||
return ff_read(args->fd, args->buf, args->len);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
ff_sys_readv(struct ff_readv_args *args)
|
||||
{
|
||||
return ff_readv(args->fd, args->iov, args->iovcnt);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
ff_sys_send(struct ff_send_args *args)
|
||||
{
|
||||
return ff_send(args->fd, args->buf, args->len, args->flags);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
ff_sys_sendto(struct ff_sendto_args *args)
|
||||
{
|
||||
return ff_sendto(args->fd, args->buf, args->len, args->flags,
|
||||
args->to, args->tolen);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
ff_sys_sendmsg(struct ff_sendmsg_args *args)
|
||||
{
|
||||
return ff_sendmsg(args->fd, args->msg, args->flags);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
ff_sys_write(struct ff_write_args *args)
|
||||
{
|
||||
return ff_write(args->fd, args->buf, args->len);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
ff_sys_writev(struct ff_writev_args *args)
|
||||
{
|
||||
return ff_writev(args->fd, args->iov, args->iovcnt);
|
||||
}
|
||||
|
||||
static int
|
||||
ff_sys_close(struct ff_close_args *args)
|
||||
{
|
||||
sockaddr_unbind(args->fd);
|
||||
return ff_close(args->fd);
|
||||
}
|
||||
|
||||
static int
|
||||
ff_sys_ioctl(struct ff_ioctl_args *args)
|
||||
{
|
||||
return ff_ioctl(args->fd, args->com, args->data);
|
||||
}
|
||||
|
||||
static int
|
||||
ff_sys_fcntl(struct ff_fcntl_args *args)
|
||||
{
|
||||
return ff_fcntl(args->fd, args->cmd, args->data);
|
||||
}
|
||||
|
||||
static int
|
||||
ff_sys_epoll_create(struct ff_epoll_create_args *args)
|
||||
{
|
||||
DEBUG_LOG("to run ff_epoll_create, size:%d\n", args->size);
|
||||
return ff_epoll_create(args->size);
|
||||
}
|
||||
|
||||
static int
|
||||
ff_sys_epoll_ctl(struct ff_epoll_ctl_args *args)
|
||||
{
|
||||
DEBUG_LOG("to run ff_epoll_ctl, epfd:%d, op:%d, fd:%d\n",
|
||||
args->epfd, args->op, args->fd);
|
||||
return ff_epoll_ctl(args->epfd, args->op, args->fd,
|
||||
args->event);
|
||||
}
|
||||
|
||||
static int
|
||||
ff_sys_epoll_wait(struct ff_epoll_wait_args *args)
|
||||
{
|
||||
DEBUG_LOG("to run ff_epoll_wait, epfd:%d, maxevents:%d, timeout:%d\n",
|
||||
args->epfd, args->maxevents, args->timeout);
|
||||
return ff_epoll_wait(args->epfd, args->events,
|
||||
args->maxevents, args->timeout);
|
||||
}
|
||||
|
||||
static int
|
||||
ff_sys_kqueue(struct ff_kqueue_args *args)
|
||||
{
|
||||
return ff_kqueue();
|
||||
}
|
||||
|
||||
static int
|
||||
ff_sys_kevent(struct ff_kevent_args *args)
|
||||
{
|
||||
return ff_kevent(args->kq, args->changelist, args->nchanges,
|
||||
args->eventlist, args->nevents, args->timeout);
|
||||
}
|
||||
|
||||
static pid_t
|
||||
ff_sys_fork(struct ff_fork_args *args)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
ff_so_handler(int ops, void *args)
|
||||
{
|
||||
DEBUG_LOG("ff_so_handler ops:%d, epoll create ops:%d\n", ops, FF_SO_EPOLL_CREATE);
|
||||
switch(ops) {
|
||||
case FF_SO_SOCKET:
|
||||
return ff_sys_socket((struct ff_socket_args *)args);
|
||||
case FF_SO_BIND:
|
||||
return ff_sys_bind((struct ff_bind_args *)args);
|
||||
case FF_SO_LISTEN:
|
||||
return ff_sys_listen((struct ff_listen_args *)args);
|
||||
case FF_SO_CONNECT:
|
||||
return ff_sys_connect((struct ff_connect_args *)args);
|
||||
case FF_SO_SHUTDOWN:
|
||||
return ff_sys_shutdown((struct ff_shutdown_args *)args);
|
||||
case FF_SO_GETSOCKNAME:
|
||||
return ff_sys_getsockname((struct ff_getsockname_args *)args);
|
||||
case FF_SO_GETPEERNAME:
|
||||
return ff_sys_getpeername((struct ff_getpeername_args *)args);
|
||||
case FF_SO_GETSOCKOPT:
|
||||
return ff_sys_getsockopt((struct ff_getsockopt_args *)args);
|
||||
case FF_SO_SETSOCKOPT:
|
||||
return ff_sys_setsockopt((struct ff_setsockopt_args *)args);
|
||||
case FF_SO_ACCEPT:
|
||||
return ff_sys_accept((struct ff_accept_args *)args);
|
||||
case FF_SO_ACCEPT4:
|
||||
return ff_sys_accept4((struct ff_accept4_args *)args);
|
||||
case FF_SO_RECV:
|
||||
return ff_sys_recv((struct ff_recv_args *)args);
|
||||
case FF_SO_RECVFROM:
|
||||
return ff_sys_recvfrom((struct ff_recvfrom_args *)args);
|
||||
case FF_SO_RECVMSG:
|
||||
return ff_sys_recvmsg((struct ff_recvmsg_args *)args);
|
||||
case FF_SO_READ:
|
||||
return ff_sys_read((struct ff_read_args *)args);
|
||||
case FF_SO_READV:
|
||||
return ff_sys_readv((struct ff_readv_args *)args);
|
||||
case FF_SO_SEND:
|
||||
return ff_sys_send((struct ff_send_args *)args);
|
||||
case FF_SO_SENDTO:
|
||||
return ff_sys_sendto((struct ff_sendto_args *)args);
|
||||
case FF_SO_SENDMSG:
|
||||
return ff_sys_sendmsg((struct ff_sendmsg_args *)args);
|
||||
case FF_SO_WRITE:
|
||||
return ff_sys_write((struct ff_write_args *)args);
|
||||
case FF_SO_WRITEV:
|
||||
return ff_sys_writev((struct ff_writev_args *)args);
|
||||
case FF_SO_CLOSE:
|
||||
return ff_sys_close((struct ff_close_args *)args);
|
||||
case FF_SO_IOCTL:
|
||||
return ff_sys_ioctl((struct ff_ioctl_args *)args);
|
||||
case FF_SO_FCNTL:
|
||||
return ff_sys_fcntl((struct ff_fcntl_args *)args);
|
||||
case FF_SO_EPOLL_CREATE:
|
||||
return ff_sys_epoll_create((struct ff_epoll_create_args *)args);
|
||||
case FF_SO_EPOLL_CTL:
|
||||
return ff_sys_epoll_ctl((struct ff_epoll_ctl_args *)args);
|
||||
case FF_SO_EPOLL_WAIT:
|
||||
return ff_sys_epoll_wait((struct ff_epoll_wait_args *)args);
|
||||
case FF_SO_KQUEUE:
|
||||
return ff_sys_kqueue((struct ff_kqueue_args *)args);
|
||||
case FF_SO_KEVENT:
|
||||
return ff_sys_kevent((struct ff_kevent_args *)args);
|
||||
case FF_SO_FORK:
|
||||
return ff_sys_fork((struct ff_fork_args *)args);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static void
|
||||
ff_handle_kevent(struct ff_so_context *sc)
|
||||
{
|
||||
struct ff_kevent_args *ka = sc->args;
|
||||
|
||||
errno = 0;
|
||||
sc->result = ff_sys_kevent(ka);
|
||||
sc->error = errno;
|
||||
|
||||
if (ka->nchanges) {
|
||||
ka->nchanges = 0;
|
||||
}
|
||||
|
||||
if (sc->result == 0 && ka->nevents != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
sc->status = FF_SC_REP;
|
||||
sem_post(&sc->wait_sem);
|
||||
}
|
||||
|
||||
static inline void
|
||||
ff_handle_socket_ops(struct ff_so_context *sc)
|
||||
{
|
||||
if (sc->inuse == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!rte_spinlock_trylock(&sc->lock)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sc->status != FF_SC_REQ) {
|
||||
rte_spinlock_unlock(&sc->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_LOG("ff_handle_socket_ops sc:%p, status:%d, ops:%d\n", sc, sc->status, sc->ops);
|
||||
|
||||
if (sc->ops == FF_SO_KEVENT) {
|
||||
ff_handle_kevent(sc);
|
||||
rte_spinlock_unlock(&sc->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
sc->result = ff_so_handler(sc->ops, sc->args);
|
||||
sc->error = errno;
|
||||
sc->status = FF_SC_REP;
|
||||
|
||||
if (sc->ops == FF_SO_EPOLL_WAIT) {
|
||||
sem_post(&sc->wait_sem);
|
||||
}
|
||||
|
||||
rte_spinlock_unlock(&sc->lock);
|
||||
}
|
||||
|
||||
void
|
||||
ff_handle_each_context()
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
rte_spinlock_lock(&ff_so_zone->lock);
|
||||
|
||||
for (i = 0; i < ff_so_zone->count; i++) {
|
||||
struct ff_so_context *sc = &ff_so_zone->sc[i];
|
||||
|
||||
ff_handle_socket_ops(sc);
|
||||
}
|
||||
|
||||
rte_spinlock_unlock(&ff_so_zone->lock);
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
#ifndef _FF_SOCKET_OPS_H_
|
||||
#define _FF_SOCKET_OPS_H_
|
||||
|
||||
#include <semaphore.h>
|
||||
|
||||
#include <rte_atomic.h>
|
||||
#include <rte_spinlock.h>
|
||||
|
||||
#define ERR_LOG(fmt, ...) do { \
|
||||
printf("file:%s, line:%u, fun:%s, "fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEBUG_LOG ERR_LOG
|
||||
#else
|
||||
#define DEBUG_LOG(...)
|
||||
#endif
|
||||
|
||||
enum FF_SOCKET_OPS {
|
||||
FF_SO_SOCKET,
|
||||
FF_SO_LISTEN,
|
||||
FF_SO_BIND,
|
||||
FF_SO_CONNECT,
|
||||
FF_SO_SHUTDOWN,
|
||||
FF_SO_GETSOCKNAME,
|
||||
FF_SO_GETPEERNAME,
|
||||
FF_SO_GETSOCKOPT,
|
||||
FF_SO_SETSOCKOPT,
|
||||
FF_SO_ACCEPT,
|
||||
FF_SO_ACCEPT4,
|
||||
FF_SO_RECV,
|
||||
FF_SO_RECVFROM,
|
||||
FF_SO_RECVMSG,
|
||||
FF_SO_READ,
|
||||
FF_SO_READV,
|
||||
FF_SO_SEND,
|
||||
FF_SO_SENDTO,
|
||||
FF_SO_SENDMSG,
|
||||
FF_SO_WRITE,
|
||||
FF_SO_WRITEV,
|
||||
FF_SO_CLOSE,
|
||||
FF_SO_IOCTL,
|
||||
FF_SO_FCNTL,
|
||||
FF_SO_EPOLL_CREATE,
|
||||
FF_SO_EPOLL_CTL,
|
||||
FF_SO_EPOLL_WAIT,
|
||||
FF_SO_KQUEUE,
|
||||
FF_SO_KEVENT,
|
||||
FF_SO_FORK,
|
||||
};
|
||||
|
||||
enum FF_SO_CONTEXT_STATUS {
|
||||
FF_SC_IDLE,
|
||||
FF_SC_REQ,
|
||||
FF_SC_REP,
|
||||
};
|
||||
|
||||
struct ff_socket_ops_zone {
|
||||
rte_spinlock_t lock;
|
||||
|
||||
/* total number of so_contex */
|
||||
uint16_t count;
|
||||
|
||||
/* free number of so_context */
|
||||
uint16_t free;
|
||||
|
||||
struct ff_so_context *sc;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct ff_so_context {
|
||||
rte_spinlock_t lock;
|
||||
|
||||
int status;
|
||||
|
||||
sem_t wait_sem;
|
||||
|
||||
enum FF_SOCKET_OPS ops;
|
||||
|
||||
void *args;
|
||||
|
||||
/* result of ops processing */
|
||||
ssize_t result;
|
||||
/* errno if failed */
|
||||
int error;
|
||||
|
||||
/* 1 if used, else 0 */
|
||||
int inuse;
|
||||
|
||||
// listen fd, refcount..
|
||||
} __attribute__((packed));
|
||||
|
||||
extern struct ff_socket_ops_zone *ff_so_zone;
|
||||
|
||||
/* For primary process */
|
||||
int ff_set_max_so_context(uint16_t count);
|
||||
int ff_create_so_memzone();
|
||||
void ff_handle_each_context();
|
||||
|
||||
/* For secondary process */
|
||||
struct ff_so_context *ff_attach_so_context(int proc_id);
|
||||
void ff_detach_so_context(struct ff_so_context *context);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,197 @@
|
|||
#ifndef _FF_SYSPROTO_H_
|
||||
#define _FF_SYSPROTO_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <time.h>
|
||||
|
||||
struct ff_socket_args {
|
||||
int domain;
|
||||
int type;
|
||||
int protocol;
|
||||
};
|
||||
|
||||
struct ff_bind_args {
|
||||
int fd;
|
||||
void *addr;
|
||||
int addrlen;
|
||||
};
|
||||
|
||||
struct ff_listen_args {
|
||||
int fd;
|
||||
int backlog;
|
||||
};
|
||||
|
||||
struct ff_shutdown_args {
|
||||
int fd;
|
||||
int how;
|
||||
};
|
||||
|
||||
struct ff_getpeername_args {
|
||||
int fd;
|
||||
void *name;
|
||||
socklen_t *namelen;
|
||||
};
|
||||
|
||||
struct ff_getsockname_args {
|
||||
int fd;
|
||||
void *name;
|
||||
socklen_t *namelen;
|
||||
};
|
||||
|
||||
struct ff_setsockopt_args {
|
||||
int fd;
|
||||
int level;
|
||||
int name;
|
||||
void *optval;
|
||||
socklen_t optlen;
|
||||
};
|
||||
|
||||
struct ff_getsockopt_args {
|
||||
int fd;
|
||||
int level;
|
||||
int name;
|
||||
void *optval;
|
||||
socklen_t *optlen;
|
||||
};
|
||||
|
||||
struct ff_accept_args {
|
||||
int fd;
|
||||
void *addr;
|
||||
socklen_t *addrlen;
|
||||
};
|
||||
|
||||
struct ff_accept4_args {
|
||||
int fd;
|
||||
void *addr;
|
||||
socklen_t *addrlen;
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct ff_connect_args {
|
||||
int fd;
|
||||
void *addr;
|
||||
int addrlen;
|
||||
};
|
||||
|
||||
struct ff_recv_args {
|
||||
int fd;
|
||||
void *buf;
|
||||
size_t len;
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct ff_recvfrom_args {
|
||||
int fd;
|
||||
void *buf;
|
||||
size_t len;
|
||||
int flags;
|
||||
void *from;
|
||||
socklen_t *fromlen;
|
||||
};
|
||||
|
||||
struct ff_recvmsg_args {
|
||||
int fd;
|
||||
struct msghdr *msg;
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct ff_read_args {
|
||||
int fd;
|
||||
void *buf;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
struct ff_readv_args {
|
||||
int fd;
|
||||
struct iovec *iov;
|
||||
int iovcnt;
|
||||
};
|
||||
|
||||
struct ff_send_args {
|
||||
int fd;
|
||||
void *buf;
|
||||
size_t len;
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct ff_sendto_args {
|
||||
int fd;
|
||||
void *buf;
|
||||
size_t len;
|
||||
int flags;
|
||||
void *to;
|
||||
int tolen;
|
||||
};
|
||||
|
||||
struct ff_sendmsg_args {
|
||||
int fd;
|
||||
struct msghdr * msg;
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct ff_write_args {
|
||||
int fd;
|
||||
void *buf;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
struct ff_writev_args {
|
||||
int fd;
|
||||
struct iovec *iov;
|
||||
int iovcnt;
|
||||
};
|
||||
|
||||
struct ff_close_args {
|
||||
int fd;
|
||||
};
|
||||
|
||||
struct ff_ioctl_args {
|
||||
int fd;
|
||||
unsigned long com;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct ff_fcntl_args {
|
||||
int fd;
|
||||
int cmd;
|
||||
long data;
|
||||
};
|
||||
|
||||
struct ff_epoll_create_args {
|
||||
int size;
|
||||
};
|
||||
|
||||
struct ff_epoll_ctl_args {
|
||||
int epfd;
|
||||
int op;
|
||||
int fd;
|
||||
struct epoll_event *event;
|
||||
};
|
||||
|
||||
struct ff_epoll_wait_args {
|
||||
int epfd;
|
||||
struct epoll_event *events;
|
||||
int maxevents;
|
||||
int timeout;
|
||||
};
|
||||
|
||||
struct ff_kqueue_args {
|
||||
|
||||
};
|
||||
|
||||
struct ff_kevent_args {
|
||||
int kq;
|
||||
struct kevent *changelist;
|
||||
int nchanges;
|
||||
struct kevent *eventlist;
|
||||
int nevents;
|
||||
struct timespec *timeout;
|
||||
};
|
||||
|
||||
struct ff_fork_args {
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,36 @@
|
|||
#include "ff_api.h"
|
||||
#include "ff_socket_ops.h"
|
||||
|
||||
#define WORKERS 32
|
||||
|
||||
int
|
||||
loop(void *arg)
|
||||
{
|
||||
ff_handle_each_context();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char * argv[])
|
||||
{
|
||||
int ret;
|
||||
|
||||
ff_init(argc, argv);
|
||||
|
||||
ret = ff_set_max_so_context(WORKERS);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = ff_create_so_memzone();
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ERR_LOG("ff_create_so_memzone successful\n");
|
||||
|
||||
ff_run(loop, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue