#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
-#include <xseg/xseg.h>
-#include <peer.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <signal.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
+
#ifdef MT
#include <pthread.h>
#endif
+#include <xseg/xseg.h>
+#include <peer.h>
+
#ifdef MT
#define PEER_TYPE "pthread"
#else
#define PEER_TYPE "posix"
#endif
+//FIXME this should not be defined here probably
+#define MAX_SPEC_LEN 128
+#define MAX_PIDFILE_LEN 512
+
volatile unsigned int terminated = 0;
unsigned int verbose = 0;
struct log_ctx lc;
#endif
#ifdef MT
+struct peerd *global_peer;
+
struct thread {
struct peerd *peer;
pthread_t tid;
{
/* ta doesn't need to be taken into account, because the main loops
* doesn't check the terminated flag if ta is not 0.
- *
+ */
+ /*
#ifdef ST_THREADS
return (!ta & terminated);
#else
{
XSEGLOG2(&lc, I, "Caught signal. Terminating gracefully");
terminated = 1;
+#ifdef MT
+ wake_up_next_thread(global_peer);
+#endif
+}
+
+void renew_logfile(int signal)
+{
+ XSEGLOG2(&lc, I, "Caught signal. Renewing logfile");
+ renew_logctx(&lc, NULL, verbose, NULL, REOPEN_FILE);
}
-static int setup_signals()
+static int setup_signals(struct peerd *peer)
{
int r;
struct sigaction sa;
+#ifdef MT
+ global_peer = peer;
+#endif
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = signal_handler;
r = sigaction(SIGQUIT, &sa, NULL);
if (r < 0)
return r;
+
+ sa.sa_handler = renew_logfile;
+ r = sigaction(SIGUSR1, &sa, NULL);
+ if (r < 0)
+ return r;
+
return r;
}
pid_t pid =syscall(SYS_gettid);
uint64_t loops;
uint64_t threshold=1000/(1 + portno_end - portno_start);
-
+
XSEGLOG2(&lc, D, "thread %u\n", (unsigned int) (t- peer->thread));
XSEGLOG2(&lc, I, "Thread %u has tid %u.\n", (unsigned int) (t- peer->thread), pid);
xseg_cancel_wait(xseg, peer->portno_start);
XSEGLOG2(&lc, I, "Thread %u woke up\n", (unsigned int) (t- peer->thread));
}
+ wake_up_next_thread(peer);
return NULL;
}
uint64_t threshold=1000/(1 + portno_end - portno_start);
pid_t pid =syscall(SYS_gettid);
uint64_t loops;
-
+
XSEGLOG2(&lc, I, "Peer has tid %u.\n", pid);
xseg_init_local_signal(xseg, peer->portno_start);
for (;!(isTerminate() && xq_count(&peer->free_reqs) == peer->nr_ops);) {
peer->portno_end= (xport) portno_end;
port = xseg_bind_port(peer->xseg, peer->portno_start, NULL);
if (!port){
- printf("cannot bind to port %ld\n", peer->portno_start);
+ printf("cannot bind to port %u\n", (unsigned int) peer->portno_start);
return NULL;
}
struct xseg_port *tmp;
tmp = xseg_bind_port(peer->xseg, p, (void *)xseg_get_signal_desc(peer->xseg, port));
if (!tmp){
- printf("cannot bind to port %ld\n", p);
+ printf("cannot bind to port %u\n", (unsigned int) p);
return NULL;
}
}
int pidfile_write(int pid_fd)
{
char buf[16];
- snprintf(buf, sizeof(buf), "%d", syscall(SYS_gettid));
+ snprintf(buf, sizeof(buf), "%ld", syscall(SYS_gettid));
buf[15] = 0;
lseek(pid_fd, 0, SEEK_SET);
return fd;
}
+void usage(char *argv0)
+{
+ fprintf(stderr, "Usage: %s [general options] [custom peer options]\n\n", argv0);
+ fprintf(stderr, "General peer options:\n"
+ " Option | Default | \n"
+ " --------------------------------------------\n"
+ " -g | None | Segment spec to join\n"
+ " -sp | NoPort | Start portno to bind\n"
+ " -ep | NoPort | End portno to bind\n"
+ " -p | NoPort | Portno to bind\n"
+ " -n | 16 | Number of ops\n"
+ " -v | 0 | Verbosity level\n"
+ " -l | None | Logfile \n"
+ " -d | No | Daemonize \n"
+ " --pidfile | None | Pidfile \n"
+#ifdef MT
+ " -t | No | Number of threads \n"
+#endif
+ "\n"
+ );
+ custom_peer_usage();
+}
+
int main(int argc, char *argv[])
{
struct peerd *peer = NULL;
//parse args
- char *spec = "";
- int i, r, daemonize = 0;
+ int r;
long portno_start = -1, portno_end = -1, portno = -1;
+
//set defaults here
+ int daemonize = 0, help = 0;
uint32_t nr_ops = 16;
- uint32_t nr_threads = 16 ;
+ uint32_t nr_threads = 1;
unsigned int debug_level = 0;
uint32_t defer_portno = NoPort;
- char *logfile = NULL;
- char *pidfile = NULL;
pid_t old_pid;
int pid_fd = -1;
+ char spec[MAX_SPEC_LEN + 1];
+ char logfile[MAX_LOGFILE_LEN + 1];
+ char pidfile[MAX_PIDFILE_LEN + 1];
+
+ logfile[0] = 0;
+ pidfile[0] = 0;
+ spec[0] = 0;
+
//capture here -g spec, -n nr_ops, -p portno, -t nr_threads -v verbose level
// -dp xseg_portno to defer blocking requests
// -l log file ?
//TODO print messages on arg parsing error
-
+ //TODO string checking
+
+ /*
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-g") && i + 1 < argc) {
spec = argv[i+1];
i += 1;
continue;
}
-
+
if (!strcmp(argv[i], "-ep") && i + 1 < argc) {
portno_end = strtoul(argv[i+1], NULL, 10);
i += 1;
}
}
- init_logctx(&lc, argv[0], debug_level, logfile);
+ */
+ BEGIN_READ_ARGS(argc, argv);
+ READ_ARG_STRING("-g", spec, MAX_SPEC_LEN);
+ READ_ARG_ULONG("-sp", portno_start);
+ READ_ARG_ULONG("-ep", portno_end);
+ READ_ARG_ULONG("-p", portno);
+ READ_ARG_ULONG("-n", nr_ops);
+ READ_ARG_ULONG("-v", debug_level);
+#ifdef MT
+ READ_ARG_ULONG("-t", nr_threads);
+#endif
+// READ_ARG_ULONG("-dp", defer_portno);
+ READ_ARG_STRING("-l", logfile, MAX_LOGFILE_LEN);
+ READ_ARG_BOOL("-d", daemonize);
+ READ_ARG_BOOL("-h", help);
+ READ_ARG_BOOL("--help", help);
+ READ_ARG_STRING("--pidfile", pidfile, MAX_PIDFILE_LEN);
+ END_READ_ARGS();
+
+ if (help){
+ usage(argv[0]);
+ return 0;
+ }
+
+ r = init_logctx(&lc, argv[0], debug_level, logfile,
+ REDIRECT_STDOUT|REDIRECT_STDERR);
+ if (r < 0){
+ XSEGLOG("Cannot initialize logging to logfile");
+ return -1;
+ }
XSEGLOG2(&lc, D, "Main thread has tid %ld.\n", syscall(SYS_gettid));
-
- if (pidfile){
+
+ if (pidfile[0]){
pid_fd = pidfile_open(pidfile, &old_pid);
if (pid_fd < 0) {
if (old_pid) {
return -1;
}
}
-
+
if (daemonize){
if (daemon(0, 1) < 0){
XSEGLOG2(&lc, E, "Cannot daemonize");
}
pidfile_write(pid_fd);
-
+
//TODO perform argument sanity checks
verbose = debug_level;
if (portno != -1) {
portno_end = portno;
}
- setup_signals();
- //TODO err check
peer = peerd_init(nr_ops, spec, portno_start, portno_end, nr_threads, defer_portno);
if (!peer){
r = -1;
goto out;
}
+ setup_signals(peer);
r = custom_peer_init(peer, argc, argv);
if (r < 0)
goto out;
#ifdef MT
+ //TODO err check
peerd_start_threads(peer);
#endif