convert source back to unix text (was DOS text)

Somehow the last set of tests added got converted to DOS text
(CRLF line terminators). Change them back

Signed-off-by: Clark Williams <williams@redhat.com>
This commit is contained in:
Clark Williams 2009-12-21 10:27:18 -06:00
parent ff74d0eb70
commit 1c3c9e34d6
10 changed files with 2250 additions and 2250 deletions

View File

@ -1,14 +1,14 @@
obj-m := backfire.o
all: modules modules_install
@echo Done
modules:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
modules_install:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules_install
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
@rm -f *.o Module.markers modules.order
obj-m := backfire.o
all: modules modules_install
@echo Done
modules:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
modules_install:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules_install
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
@rm -f *.o Module.markers modules.order

View File

@ -1,150 +1,150 @@
/*
* backfire - send signal back to caller
*
* Copyright (C) 2007 Carsten Emde <C.Emde@osadl.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/cpumask.h>
#include <linux/time.h>
#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#define BACKFIRE_MINOR MISC_DYNAMIC_MINOR
static spinlock_t backfire_state_lock = SPIN_LOCK_UNLOCKED;
static int backfire_open_cnt; /* #times opened */
static int backfire_open_mode; /* special open modes */
static struct timeval sendtime; /* when the most recent signal was sent */
#define BACKFIRE_WRITE 1 /* opened for writing (exclusive) */
#define BACKFIRE_EXCL 2 /* opened with O_EXCL */
/*
* These are the file operation function for user access to /dev/backfire
*/
static ssize_t
backfire_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
return snprintf(buf, count, "%d,%d\n", (int) sendtime.tv_sec,
(int) sendtime.tv_usec);
}
static ssize_t
backfire_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
int signo;
struct pid *pid;
if (sscanf(buf, "%d", &signo) >= 1) {
if (signo > 0 && signo < 32) {
pid = get_pid(task_pid(current));
do_gettimeofday(&sendtime);
kill_pid(pid, signo, 1);
} else
printk(KERN_ERR "Invalid signal no. %d\n", signo);
}
return strlen(buf);
}
static int
backfire_open(struct inode *inode, struct file *file)
{
spin_lock(&backfire_state_lock);
if ((backfire_open_cnt && (file->f_flags & O_EXCL)) ||
(backfire_open_mode & BACKFIRE_EXCL)) {
spin_unlock(&backfire_state_lock);
return -EBUSY;
}
if (file->f_flags & O_EXCL)
backfire_open_mode |= BACKFIRE_EXCL;
if (file->f_mode & 2)
backfire_open_mode |= BACKFIRE_WRITE;
backfire_open_cnt++;
spin_unlock(&backfire_state_lock);
return 0;
}
static int
backfire_release(struct inode *inode, struct file *file)
{
spin_lock(&backfire_state_lock);
backfire_open_cnt--;
if (backfire_open_cnt == 1 && backfire_open_mode & BACKFIRE_EXCL)
backfire_open_mode &= ~BACKFIRE_EXCL;
if (file->f_mode & 2)
backfire_open_mode &= ~BACKFIRE_WRITE;
spin_unlock(&backfire_state_lock);
return 0;
}
static struct file_operations backfire_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.open = backfire_open,
.read = backfire_read,
.write = backfire_write,
.release = backfire_release,
};
static struct miscdevice backfire_dev = {
BACKFIRE_MINOR,
"backfire",
&backfire_fops
};
static int __init backfire_init(void)
{
int ret;
ret = misc_register(&backfire_dev);
if (ret)
printk(KERN_ERR "backfire: can't register dynamic misc device\n");
else
printk(KERN_INFO "backfire driver v__VERSION_STRING__ misc device %d\n",
backfire_dev.minor);
return ret;
}
static void __exit backfire_exit(void)
{
misc_deregister(&backfire_dev);
}
module_init(backfire_init);
module_exit(backfire_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Carsten Emde <C.Emde@osadl.org>");
MODULE_DESCRIPTION("Send signal back to caller");
/*
* backfire - send signal back to caller
*
* Copyright (C) 2007 Carsten Emde <C.Emde@osadl.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/cpumask.h>
#include <linux/time.h>
#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#define BACKFIRE_MINOR MISC_DYNAMIC_MINOR
static spinlock_t backfire_state_lock = SPIN_LOCK_UNLOCKED;
static int backfire_open_cnt; /* #times opened */
static int backfire_open_mode; /* special open modes */
static struct timeval sendtime; /* when the most recent signal was sent */
#define BACKFIRE_WRITE 1 /* opened for writing (exclusive) */
#define BACKFIRE_EXCL 2 /* opened with O_EXCL */
/*
* These are the file operation function for user access to /dev/backfire
*/
static ssize_t
backfire_read(struct file *file, char *buf, size_t count, loff_t *ppos)
{
return snprintf(buf, count, "%d,%d\n", (int) sendtime.tv_sec,
(int) sendtime.tv_usec);
}
static ssize_t
backfire_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
int signo;
struct pid *pid;
if (sscanf(buf, "%d", &signo) >= 1) {
if (signo > 0 && signo < 32) {
pid = get_pid(task_pid(current));
do_gettimeofday(&sendtime);
kill_pid(pid, signo, 1);
} else
printk(KERN_ERR "Invalid signal no. %d\n", signo);
}
return strlen(buf);
}
static int
backfire_open(struct inode *inode, struct file *file)
{
spin_lock(&backfire_state_lock);
if ((backfire_open_cnt && (file->f_flags & O_EXCL)) ||
(backfire_open_mode & BACKFIRE_EXCL)) {
spin_unlock(&backfire_state_lock);
return -EBUSY;
}
if (file->f_flags & O_EXCL)
backfire_open_mode |= BACKFIRE_EXCL;
if (file->f_mode & 2)
backfire_open_mode |= BACKFIRE_WRITE;
backfire_open_cnt++;
spin_unlock(&backfire_state_lock);
return 0;
}
static int
backfire_release(struct inode *inode, struct file *file)
{
spin_lock(&backfire_state_lock);
backfire_open_cnt--;
if (backfire_open_cnt == 1 && backfire_open_mode & BACKFIRE_EXCL)
backfire_open_mode &= ~BACKFIRE_EXCL;
if (file->f_mode & 2)
backfire_open_mode &= ~BACKFIRE_WRITE;
spin_unlock(&backfire_state_lock);
return 0;
}
static struct file_operations backfire_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.open = backfire_open,
.read = backfire_read,
.write = backfire_write,
.release = backfire_release,
};
static struct miscdevice backfire_dev = {
BACKFIRE_MINOR,
"backfire",
&backfire_fops
};
static int __init backfire_init(void)
{
int ret;
ret = misc_register(&backfire_dev);
if (ret)
printk(KERN_ERR "backfire: can't register dynamic misc device\n");
else
printk(KERN_INFO "backfire driver v__VERSION_STRING__ misc device %d\n",
backfire_dev.minor);
return ret;
}
static void __exit backfire_exit(void)
{
misc_deregister(&backfire_dev);
}
module_init(backfire_init);
module_exit(backfire_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Carsten Emde <C.Emde@osadl.org>");
MODULE_DESCRIPTION("Send signal back to caller");

View File

@ -1,291 +1,291 @@
/*
* sendme.c
*
* Copyright (C) 2009 Carsten Emde <C.Emde@osadl.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#define __USE_GNU
#include <fcntl.h>
#include <getopt.h>
#include <signal.h>
#include <sched.h>
#include <string.h>
#include <time.h>
#include "rt-utils.h"
#define _GNU_SOURCE
#include <utmpx.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/mman.h>
#define USEC_PER_SEC 1000000
#define NSEC_PER_SEC 1000000000
#define SIGTEST SIGHUP
enum {
AFFINITY_UNSPECIFIED,
AFFINITY_SPECIFIED,
AFFINITY_USECURRENT
};
static int setaffinity = AFFINITY_UNSPECIFIED;
static int affinity;
static int tracelimit;
static int priority;
static int shutdown;
static int max_cycles;
static volatile struct timeval after;
static int interval = 1000;
static int kernvar(int mode, const char *name, char *value, size_t sizeofvalue)
{
char filename[128];
char *fileprefix = get_debugfileprefix();
int retval = 1;
int path;
strncpy(filename, fileprefix, sizeof(filename));
strncat(filename, name, sizeof(filename) - strlen(fileprefix));
path = open(filename, mode);
if (path >= 0) {
if (mode == O_RDONLY) {
int got;
if ((got = read(path, value, sizeofvalue)) > 0) {
retval = 0;
value[got-1] = '\0';
}
} else if (mode == O_WRONLY) {
if (write(path, value, sizeofvalue) == sizeofvalue)
retval = 0;
}
close(path);
}
return retval;
}
void signalhandler(int signo)
{
struct timeval tv;
gettimeofday(&tv, NULL);
after = tv;
if (signo == SIGINT || signo == SIGTERM)
shutdown = 1;
}
void stop_tracing(void)
{
kernvar(O_WRONLY, "tracing_enabled", "0", 1);
}
static void display_help(void)
{
printf("sendme V %1.2f\n", VERSION_STRING);
puts("Usage: sendme <options>");
puts("Function: send a signal from driver to userspace");
puts(
"Options:\n"
"-a [NUM] --affinity pin to current processor\n"
" with NUM pin to processor NUM\n"
"-b USEC --breaktrace=USEC send break trace command when latency > USEC\n"
"-i INTV --interval=INTV base interval of thread in us default=1000\n"
"-l LOOPS --loops=LOOPS number of loops: default=0(endless)\n"
"-p PRIO --prio=PRIO priority\n");
exit(1);
}
static void process_options (int argc, char *argv[])
{
int error = 0;
int max_cpus = sysconf(_SC_NPROCESSORS_CONF);
for (;;) {
int option_index = 0;
/** Options for getopt */
static struct option long_options[] = {
{"affinity", optional_argument, NULL, 'a'},
{"breaktrace", required_argument, NULL, 'b'},
{"interval", required_argument, NULL, 'i'},
{"loops", required_argument, NULL, 'l'},
{"priority", required_argument, NULL, 'p'},
{"help", no_argument, NULL, '?'},
{NULL, 0, NULL, 0}
};
int c = getopt_long (argc, argv, "a::b:i:l:p:",
long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 'a':
if (optarg != NULL) {
affinity = atoi(optarg);
setaffinity = AFFINITY_SPECIFIED;
} else if (optind < argc && atoi(argv[optind])) {
affinity = atoi(argv[optind]);
setaffinity = AFFINITY_SPECIFIED;
} else
setaffinity = AFFINITY_USECURRENT;
break;
case 'b': tracelimit = atoi(optarg); break;
case 'i': interval = atoi(optarg); break;
case 'l': max_cycles = atoi(optarg); break;
case 'p': priority = atoi(optarg); break;
case '?': error = 1; break;
}
}
if (setaffinity == AFFINITY_SPECIFIED) {
if (affinity < 0)
error = 1;
if (affinity >= max_cpus) {
fprintf(stderr, "ERROR: CPU #%d not found, only %d CPUs available\n",
affinity, max_cpus);
error = 1;
}
}
if (priority < 0 || priority > 99)
error = 1;
if (error)
display_help ();
}
int main(int argc, char *argv[])
{
int path;
cpu_set_t mask;
int policy = SCHED_FIFO;
struct sched_param schedp;
struct flock fl;
int retval = 0;
process_options(argc, argv);
if (check_privs())
return 1;
if (mlockall(MCL_CURRENT|MCL_FUTURE) == -1) {
perror("mlockall");
return 1;
}
memset(&schedp, 0, sizeof(schedp));
schedp.sched_priority = priority;
sched_setscheduler(0, policy, &schedp);
if (setaffinity != AFFINITY_UNSPECIFIED) {
CPU_ZERO(&mask);
if (setaffinity == AFFINITY_USECURRENT)
affinity = sched_getcpu();
CPU_SET(affinity, &mask);
if (sched_setaffinity(0, sizeof(mask), &mask) == -1)
fprintf(stderr, "WARNING: Could not set CPU affinity "
"to CPU #%d\n", affinity);
}
path = open("/dev/backfire", O_RDWR);
if (path < 0) {
fprintf(stderr, "ERROR: Could not access backfire device, "
"try 'modprobe backfire'\n");
return 1;
}
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 1;
if (fcntl(path, F_SETLK, &fl) == -1) {
fprintf(stderr, "ERRROR: backfire device locked\n");
retval = 1;
} else {
char sigtest[8];
char timestamp[32];
struct timeval before, sendtime, diff;
unsigned int diffno = 0;
unsigned int mindiff1 = UINT_MAX, maxdiff1 = 0;
unsigned int mindiff2 = UINT_MAX, maxdiff2 = 0;
double sumdiff1 = 0.0, sumdiff2 = 0.0;
if (tracelimit)
kernvar(O_WRONLY, "tracing_enabled", "1", 1);
sprintf(sigtest, "%d", SIGTEST);
signal(SIGTEST, signalhandler);
signal(SIGINT, signalhandler);
signal(SIGTERM, signalhandler);
while (1) {
struct timespec ts;
ts.tv_sec = interval / USEC_PER_SEC;
ts.tv_nsec = (interval % USEC_PER_SEC) * 1000;
gettimeofday(&before, NULL);
write(path, sigtest, strlen(sigtest));
while (after.tv_sec == 0);
read(path, timestamp, sizeof(timestamp));
if (sscanf(timestamp, "%lu,%lu\n", &sendtime.tv_sec,
&sendtime.tv_usec) != 2)
break;
diffno++;
if(max_cycles && diffno >= max_cycles)
shutdown = 1;
printf("Samples: %8d\n", diffno);
timersub(&sendtime, &before, &diff);
if (diff.tv_usec < mindiff1)
mindiff1 = diff.tv_usec;
if (diff.tv_usec > maxdiff1)
maxdiff1 = diff.tv_usec;
sumdiff1 += (double) diff.tv_usec;
printf("To: Min %4d, Cur %4d, Avg %4d, Max %4d\n",
mindiff1, (int) diff.tv_usec,
(int) ((sumdiff1 / diffno) + 0.5),
maxdiff1);
timersub(&after, &sendtime, &diff);
if (diff.tv_usec < mindiff2)
mindiff2 = diff.tv_usec;
if (diff.tv_usec > maxdiff2)
maxdiff2 = diff.tv_usec;
sumdiff2 += (double) diff.tv_usec;
printf("From: Min %4d, Cur %4d, Avg %4d, Max %4d\n",
mindiff2, (int) diff.tv_usec,
(int) ((sumdiff2 / diffno) + 0.5),
maxdiff2);
after.tv_sec = 0;
if ((tracelimit && diff.tv_usec > tracelimit) ||
shutdown) {
if (tracelimit)
stop_tracing();
break;
}
nanosleep(&ts, NULL);
printf("\033[3A");
}
}
close(path);
return retval;
}
/*
* sendme.c
*
* Copyright (C) 2009 Carsten Emde <C.Emde@osadl.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#define __USE_GNU
#include <fcntl.h>
#include <getopt.h>
#include <signal.h>
#include <sched.h>
#include <string.h>
#include <time.h>
#include "rt-utils.h"
#define _GNU_SOURCE
#include <utmpx.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/mman.h>
#define USEC_PER_SEC 1000000
#define NSEC_PER_SEC 1000000000
#define SIGTEST SIGHUP
enum {
AFFINITY_UNSPECIFIED,
AFFINITY_SPECIFIED,
AFFINITY_USECURRENT
};
static int setaffinity = AFFINITY_UNSPECIFIED;
static int affinity;
static int tracelimit;
static int priority;
static int shutdown;
static int max_cycles;
static volatile struct timeval after;
static int interval = 1000;
static int kernvar(int mode, const char *name, char *value, size_t sizeofvalue)
{
char filename[128];
char *fileprefix = get_debugfileprefix();
int retval = 1;
int path;
strncpy(filename, fileprefix, sizeof(filename));
strncat(filename, name, sizeof(filename) - strlen(fileprefix));
path = open(filename, mode);
if (path >= 0) {
if (mode == O_RDONLY) {
int got;
if ((got = read(path, value, sizeofvalue)) > 0) {
retval = 0;
value[got-1] = '\0';
}
} else if (mode == O_WRONLY) {
if (write(path, value, sizeofvalue) == sizeofvalue)
retval = 0;
}
close(path);
}
return retval;
}
void signalhandler(int signo)
{
struct timeval tv;
gettimeofday(&tv, NULL);
after = tv;
if (signo == SIGINT || signo == SIGTERM)
shutdown = 1;
}
void stop_tracing(void)
{
kernvar(O_WRONLY, "tracing_enabled", "0", 1);
}
static void display_help(void)
{
printf("sendme V %1.2f\n", VERSION_STRING);
puts("Usage: sendme <options>");
puts("Function: send a signal from driver to userspace");
puts(
"Options:\n"
"-a [NUM] --affinity pin to current processor\n"
" with NUM pin to processor NUM\n"
"-b USEC --breaktrace=USEC send break trace command when latency > USEC\n"
"-i INTV --interval=INTV base interval of thread in us default=1000\n"
"-l LOOPS --loops=LOOPS number of loops: default=0(endless)\n"
"-p PRIO --prio=PRIO priority\n");
exit(1);
}
static void process_options (int argc, char *argv[])
{
int error = 0;
int max_cpus = sysconf(_SC_NPROCESSORS_CONF);
for (;;) {
int option_index = 0;
/** Options for getopt */
static struct option long_options[] = {
{"affinity", optional_argument, NULL, 'a'},
{"breaktrace", required_argument, NULL, 'b'},
{"interval", required_argument, NULL, 'i'},
{"loops", required_argument, NULL, 'l'},
{"priority", required_argument, NULL, 'p'},
{"help", no_argument, NULL, '?'},
{NULL, 0, NULL, 0}
};
int c = getopt_long (argc, argv, "a::b:i:l:p:",
long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 'a':
if (optarg != NULL) {
affinity = atoi(optarg);
setaffinity = AFFINITY_SPECIFIED;
} else if (optind < argc && atoi(argv[optind])) {
affinity = atoi(argv[optind]);
setaffinity = AFFINITY_SPECIFIED;
} else
setaffinity = AFFINITY_USECURRENT;
break;
case 'b': tracelimit = atoi(optarg); break;
case 'i': interval = atoi(optarg); break;
case 'l': max_cycles = atoi(optarg); break;
case 'p': priority = atoi(optarg); break;
case '?': error = 1; break;
}
}
if (setaffinity == AFFINITY_SPECIFIED) {
if (affinity < 0)
error = 1;
if (affinity >= max_cpus) {
fprintf(stderr, "ERROR: CPU #%d not found, only %d CPUs available\n",
affinity, max_cpus);
error = 1;
}
}
if (priority < 0 || priority > 99)
error = 1;
if (error)
display_help ();
}
int main(int argc, char *argv[])
{
int path;
cpu_set_t mask;
int policy = SCHED_FIFO;
struct sched_param schedp;
struct flock fl;
int retval = 0;
process_options(argc, argv);
if (check_privs())
return 1;
if (mlockall(MCL_CURRENT|MCL_FUTURE) == -1) {
perror("mlockall");
return 1;
}
memset(&schedp, 0, sizeof(schedp));
schedp.sched_priority = priority;
sched_setscheduler(0, policy, &schedp);
if (setaffinity != AFFINITY_UNSPECIFIED) {
CPU_ZERO(&mask);
if (setaffinity == AFFINITY_USECURRENT)
affinity = sched_getcpu();
CPU_SET(affinity, &mask);
if (sched_setaffinity(0, sizeof(mask), &mask) == -1)
fprintf(stderr, "WARNING: Could not set CPU affinity "
"to CPU #%d\n", affinity);
}
path = open("/dev/backfire", O_RDWR);
if (path < 0) {
fprintf(stderr, "ERROR: Could not access backfire device, "
"try 'modprobe backfire'\n");
return 1;
}
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 1;
if (fcntl(path, F_SETLK, &fl) == -1) {
fprintf(stderr, "ERRROR: backfire device locked\n");
retval = 1;
} else {
char sigtest[8];
char timestamp[32];
struct timeval before, sendtime, diff;
unsigned int diffno = 0;
unsigned int mindiff1 = UINT_MAX, maxdiff1 = 0;
unsigned int mindiff2 = UINT_MAX, maxdiff2 = 0;
double sumdiff1 = 0.0, sumdiff2 = 0.0;
if (tracelimit)
kernvar(O_WRONLY, "tracing_enabled", "1", 1);
sprintf(sigtest, "%d", SIGTEST);
signal(SIGTEST, signalhandler);
signal(SIGINT, signalhandler);
signal(SIGTERM, signalhandler);
while (1) {
struct timespec ts;
ts.tv_sec = interval / USEC_PER_SEC;
ts.tv_nsec = (interval % USEC_PER_SEC) * 1000;
gettimeofday(&before, NULL);
write(path, sigtest, strlen(sigtest));
while (after.tv_sec == 0);
read(path, timestamp, sizeof(timestamp));
if (sscanf(timestamp, "%lu,%lu\n", &sendtime.tv_sec,
&sendtime.tv_usec) != 2)
break;
diffno++;
if(max_cycles && diffno >= max_cycles)
shutdown = 1;
printf("Samples: %8d\n", diffno);
timersub(&sendtime, &before, &diff);
if (diff.tv_usec < mindiff1)
mindiff1 = diff.tv_usec;
if (diff.tv_usec > maxdiff1)
maxdiff1 = diff.tv_usec;
sumdiff1 += (double) diff.tv_usec;
printf("To: Min %4d, Cur %4d, Avg %4d, Max %4d\n",
mindiff1, (int) diff.tv_usec,
(int) ((sumdiff1 / diffno) + 0.5),
maxdiff1);
timersub(&after, &sendtime, &diff);
if (diff.tv_usec < mindiff2)
mindiff2 = diff.tv_usec;
if (diff.tv_usec > maxdiff2)
maxdiff2 = diff.tv_usec;
sumdiff2 += (double) diff.tv_usec;
printf("From: Min %4d, Cur %4d, Avg %4d, Max %4d\n",
mindiff2, (int) diff.tv_usec,
(int) ((sumdiff2 / diffno) + 0.5),
maxdiff2);
after.tv_sec = 0;
if ((tracelimit && diff.tv_usec > tracelimit) ||
shutdown) {
if (tracelimit)
stop_tracing();
break;
}
nanosleep(&ts, NULL);
printf("\033[3A");
}
}
close(path);
return retval;
}

View File

@ -1 +1 @@
#define VERSION "0.5"
#define VERSION "0.5"

View File

@ -1,16 +1,16 @@
CFLAGS += -Wall -O2
LDFLAGS += -lpthread
all: ptsematest
@echo Done
ptsematest.o: ptsematest.c
ptsematest:
clean:
@rm -f *.o
tar: clean
@rm -f ptsematest
$(shell bn=`basename $$PWD`; cd ..; tar -zcf $$bn.tgz $$bn)
CFLAGS += -Wall -O2
LDFLAGS += -lpthread
all: ptsematest
@echo Done
ptsematest.o: ptsematest.c
ptsematest:
clean:
@rm -f *.o
tar: clean
@rm -f ptsematest
$(shell bn=`basename $$PWD`; cd ..; tar -zcf $$bn.tgz $$bn)

View File

@ -1,423 +1,423 @@
/*
* ptsematest.c
*
* Copyright (C) 2009 Carsten Emde <C.Emde@osadl.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <fcntl.h>
#include <getopt.h>
#include <signal.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <linux/unistd.h>
#include <utmpx.h>
#include "rt-utils.h"
#define __USE_GNU
#include <pthread.h>
#define gettid() syscall(__NR_gettid)
#define USEC_PER_SEC 1000000
enum {
AFFINITY_UNSPECIFIED,
AFFINITY_SPECIFIED,
AFFINITY_USEALL
};
static pthread_mutex_t *testmutex;
static pthread_mutex_t *syncmutex;
struct params {
int num;
int cpu;
int priority;
int affinity;
int sender;
int samples;
int max_cycles;
int tracelimit;
int tid;
int shutdown;
int stopped;
struct timespec delay;
unsigned int mindiff, maxdiff;
double sumdiff;
struct timeval unblocked, received, diff;
pthread_t threadid;
struct params *neighbor;
char error[MAX_PATH * 2];
};
void *semathread(void *param)
{
int mustgetcpu = 0;
int first = 1;
struct params *par = param;
cpu_set_t mask;
int policy = SCHED_FIFO;
struct sched_param schedp;
memset(&schedp, 0, sizeof(schedp));
schedp.sched_priority = par->priority;
sched_setscheduler(0, policy, &schedp);
if (par->cpu != -1) {
CPU_ZERO(&mask);
CPU_SET(par->cpu, &mask);
if(sched_setaffinity(0, sizeof(mask), &mask) == -1)
fprintf(stderr, "WARNING: Could not set CPU affinity "
"to CPU #%d\n", par->cpu);
} else
mustgetcpu = 1;
par->tid = gettid();
while (!par->shutdown) {
if (par->sender) {
pthread_mutex_lock(&syncmutex[par->num]);
/* Release lock: Start of latency measurement ... */
gettimeofday(&par->unblocked, NULL);
pthread_mutex_unlock(&testmutex[par->num]);
par->samples++;
if(par->max_cycles && par->samples >= par->max_cycles)
par->shutdown = 1;
if (mustgetcpu) {
par->cpu = sched_getcpu();
}
} else {
/* Receiver */
if (!first) {
pthread_mutex_lock(&syncmutex[par->num]);
first = 1;
}
pthread_mutex_lock(&testmutex[par->num]);
/* ... Got the lock: End of latency measurement */
gettimeofday(&par->received, NULL);
par->samples++;
timersub(&par->received, &par->neighbor->unblocked,
&par->diff);
if (par->diff.tv_usec < par->mindiff)
par->mindiff = par->diff.tv_usec;
if (par->diff.tv_usec > par->maxdiff)
par->maxdiff = par->diff.tv_usec;
par->sumdiff += (double) par->diff.tv_usec;
if (par->tracelimit && par->maxdiff > par->tracelimit) {
char tracing_enabled_file[MAX_PATH];
strcpy(tracing_enabled_file, get_debugfileprefix());
strcat(tracing_enabled_file, "tracing_enabled");
int tracing_enabled =
open(tracing_enabled_file, O_WRONLY);
if (tracing_enabled >= 0) {
write(tracing_enabled, "0", 1);
close(tracing_enabled);
} else
snprintf(par->error, sizeof(par->error),
"Could not access %s\n",
tracing_enabled_file);
par->shutdown = 1;
par->neighbor->shutdown = 1;
}
if (par->max_cycles && par->samples >= par->max_cycles)
par->shutdown = 1;
if (mustgetcpu) {
par->cpu = sched_getcpu();
}
nanosleep(&par->delay, NULL);
pthread_mutex_unlock(&syncmutex[par->num]);
}
}
par->stopped = 1;
return NULL;
}
static void display_help(void)
{
printf("ptsematest V %1.2f\n", VERSION_STRING);
puts("Usage: ptsematest <options>");
puts("Function: test POSIX threads mutex latency");
puts(
"Options:\n"
"-a [NUM] --affinity run thread #N on processor #N, if possible\n"
" with NUM pin all threads to the processor NUM\n"
"-b USEC --breaktrace=USEC send break trace command when latency > USEC\n"
"-d DIST --distance=DIST distance of thread intervals in us default=500\n"
"-i INTV --interval=INTV base interval of thread in us default=1000\n"
"-l LOOPS --loops=LOOPS number of loops: default=0(endless)\n"
"-p PRIO --prio=PRIO priority\n"
"-t --threads one thread per available processor\n"
"-t [NUM] --threads=NUM number of threads:\n"
" without NUM, threads = max_cpus\n"
" without -t default = 1\n");
exit(1);
}
static int setaffinity = AFFINITY_UNSPECIFIED;
static int affinity;
static int tracelimit;
static int priority;
static int num_threads = 1;
static int max_cycles;
static int interval = 1000;
static int distance = 500;
static void process_options (int argc, char *argv[])
{
int error = 0;
int max_cpus = sysconf(_SC_NPROCESSORS_CONF);
for (;;) {
int option_index = 0;
/** Options for getopt */
static struct option long_options[] = {
{"affinity", optional_argument, NULL, 'a'},
{"breaktrace", required_argument, NULL, 'b'},
{"distance", required_argument, NULL, 'd'},
{"interval", required_argument, NULL, 'i'},
{"loops", required_argument, NULL, 'l'},
{"priority", required_argument, NULL, 'p'},
{"threads", optional_argument, NULL, 't'},
{"help", no_argument, NULL, '?'},
{NULL, 0, NULL, 0}
};
int c = getopt_long (argc, argv, "a::b:d:i:l:p:t::",
long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 'a':
if (optarg != NULL) {
affinity = atoi(optarg);
setaffinity = AFFINITY_SPECIFIED;
} else if (optind<argc && atoi(argv[optind])) {
affinity = atoi(argv[optind]);
setaffinity = AFFINITY_SPECIFIED;
} else {
setaffinity = AFFINITY_USEALL;
}
break;
case 'b': tracelimit = atoi(optarg); break;
case 'd': distance = atoi(optarg); break;
case 'i': interval = atoi(optarg); break;
case 'l': max_cycles = atoi(optarg); break;
case 'p': priority = atoi(optarg); break;
case 't':
if (optarg != NULL)
num_threads = atoi(optarg);
else if (optind<argc && atoi(argv[optind]))
num_threads = atoi(argv[optind]);
else
num_threads = max_cpus;
break;
case '?': error = 1; break;
}
}
if (setaffinity == AFFINITY_SPECIFIED) {
if (affinity < 0)
error = 1;
if (affinity >= max_cpus) {
fprintf(stderr, "ERROR: CPU #%d not found, only %d CPUs available\n",
affinity, max_cpus);
error = 1;
}
}
if (num_threads < 0 || num_threads > 255)
error = 1;
if (priority < 0 || priority > 99)
error = 1;
if (num_threads < 1)
error = 1;
if (error)
display_help ();
}
static int volatile shutdown;
static void sighand(int sig)
{
shutdown = 1;
}
int main(int argc, char *argv[])
{
int i;
int max_cpus = sysconf(_SC_NPROCESSORS_CONF);
int oldsamples = 1;
struct params *receiver = NULL;
struct params *sender = NULL;
sigset_t sigset;
struct timespec maindelay;
process_options(argc, argv);
if (check_privs())
return 1;
if (mlockall(MCL_CURRENT|MCL_FUTURE) == -1) {
perror("mlockall");
return 1;
}
signal(SIGINT, sighand);
signal(SIGTERM, sighand);
receiver = calloc(num_threads, sizeof(struct params));
sender = calloc(num_threads, sizeof(struct params));
if (receiver == NULL || sender == NULL)
goto nomem;
testmutex = (pthread_mutex_t *) calloc(num_threads, sizeof(pthread_mutex_t));
syncmutex = (pthread_mutex_t *) calloc(num_threads, sizeof(pthread_mutex_t));
if (testmutex == NULL || syncmutex == NULL)
goto nomem;
for (i = 0; i < num_threads; i++) {
receiver[i].mindiff = UINT_MAX;
receiver[i].maxdiff = 0;
receiver[i].sumdiff = 0.0;
pthread_mutex_init(&testmutex[i], NULL);
pthread_mutex_init(&syncmutex[i], NULL);
/* Wait on first attempt */
pthread_mutex_lock(&testmutex[i]);
receiver[i].num = i;
receiver[i].cpu = i;
switch (setaffinity) {
case AFFINITY_UNSPECIFIED: receiver[i].cpu = -1; break;
case AFFINITY_SPECIFIED: receiver[i].cpu = affinity; break;
case AFFINITY_USEALL: receiver[i].cpu = i % max_cpus; break;
}
receiver[i].priority = priority;
receiver[i].tracelimit = tracelimit;
if (priority > 0)
priority--;
receiver[i].delay.tv_sec = interval / USEC_PER_SEC;
receiver[i].delay.tv_nsec = (interval % USEC_PER_SEC) * 1000;
interval += distance;
receiver[i].max_cycles = max_cycles;
receiver[i].sender = 0;
receiver[i].neighbor = &sender[i];
pthread_create(&receiver[i].threadid, NULL, semathread, &receiver[i]);
memcpy(&sender[i], &receiver[i], sizeof(receiver[0]));
sender[i].sender = 1;
sender[i].neighbor = &receiver[i];
pthread_create(&sender[i].threadid, NULL, semathread, &sender[i]);
}
maindelay.tv_sec = 0;
maindelay.tv_nsec = 50000000; /* 50 ms */
while (!shutdown) {
int printed;
int errorlines = 0;
for (i = 0; i < num_threads; i++)
shutdown |= receiver[i].shutdown | sender[i].shutdown;
if (receiver[0].samples > oldsamples || shutdown) {
for (i = 0; i < num_threads; i++) {
printf("#%1d: ID%d, P%d, CPU%d, I%ld; #%1d: ID%d, P%d, CPU%d, Cycles %d\n",
i*2, receiver[i].tid, receiver[i].priority, receiver[i].cpu,
receiver[i].delay.tv_nsec / 1000,
i*2+1, sender[i].tid, sender[i].priority, sender[i].cpu,
sender[i].samples);
}
for (i = 0; i < num_threads; i++) {
printf("#%d -> #%d, Min %4d, Cur %4d, Avg %4d, Max %4d\n",
i*2+1, i*2,
receiver[i].mindiff, (int) receiver[i].diff.tv_usec,
(int) ((receiver[i].sumdiff / receiver[i].samples) + 0.5),
receiver[i].maxdiff);
if (receiver[i].error[0] != '\0') {
printf(receiver[i].error);
errorlines++;
receiver[i].error[0] = '\0';
}
if (sender[i].error[0] != '\0') {
printf(sender[i].error);
errorlines++;
receiver[i].error[0] = '\0';
}
}
printed = 1;
} else
printed = 0;
sigemptyset(&sigset);
sigaddset(&sigset, SIGTERM);
sigaddset(&sigset, SIGINT);
pthread_sigmask(SIG_SETMASK, &sigset, NULL);
nanosleep(&maindelay, NULL);
sigemptyset(&sigset);
pthread_sigmask(SIG_SETMASK, &sigset, NULL);
if (printed && !shutdown)
printf("\033[%dA", num_threads*2 + errorlines);
}
for (i = 0; i < num_threads; i++) {
receiver[i].shutdown = 1;
sender[i].shutdown = 1;
pthread_mutex_unlock(&testmutex[i]);
pthread_mutex_unlock(&syncmutex[i]);
}
nanosleep(&receiver[0].delay, NULL);
for (i = 0; i < num_threads; i++) {
if (!receiver[i].stopped)
pthread_kill(receiver[i].threadid, SIGTERM);
if (!sender[i].stopped)
pthread_kill(sender[i].threadid, SIGTERM);
}
for (i = 0; i < num_threads; i++) {
pthread_mutex_destroy(&testmutex[i]);
pthread_mutex_destroy(&syncmutex[i]);
}
nomem:
return 0;
}
/*
* ptsematest.c
*
* Copyright (C) 2009 Carsten Emde <C.Emde@osadl.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
* USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <fcntl.h>
#include <getopt.h>
#include <signal.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <linux/unistd.h>
#include <utmpx.h>
#include "rt-utils.h"
#define __USE_GNU
#include <pthread.h>
#define gettid() syscall(__NR_gettid)
#define USEC_PER_SEC 1000000
enum {
AFFINITY_UNSPECIFIED,
AFFINITY_SPECIFIED,
AFFINITY_USEALL
};
static pthread_mutex_t *testmutex;
static pthread_mutex_t *syncmutex;
struct params {
int num;
int cpu;
int priority;
int affinity;
int sender;
int samples;
int max_cycles;
int tracelimit;
int tid;
int shutdown;
int stopped;
struct timespec delay;
unsigned int mindiff, maxdiff;
double sumdiff;
struct timeval unblocked, received, diff;
pthread_t threadid;
struct params *neighbor;
char error[MAX_PATH * 2];
};
void *semathread(void *param)
{
int mustgetcpu = 0;
int first = 1;
struct params *par = param;
cpu_set_t mask;
int policy = SCHED_FIFO;
struct sched_param schedp;
memset(&schedp, 0, sizeof(schedp));
schedp.sched_priority = par->priority;
sched_setscheduler(0, policy, &schedp);
if (par->cpu != -1) {
CPU_ZERO(&mask);
CPU_SET(par->cpu, &mask);
if(sched_setaffinity(0, sizeof(mask), &mask) == -1)
fprintf(stderr, "WARNING: Could not set CPU affinity "
"to CPU #%d\n", par->cpu);
} else
mustgetcpu = 1;
par->tid = gettid();
while (!par->shutdown) {
if (par->sender) {
pthread_mutex_lock(&syncmutex[par->num]);
/* Release lock: Start of latency measurement ... */
gettimeofday(&par->unblocked, NULL);
pthread_mutex_unlock(&testmutex[par->num]);
par->samples++;
if(par->max_cycles && par->samples >= par->max_cycles)
par->shutdown = 1;
if (mustgetcpu) {
par->cpu = sched_getcpu();
}
} else {
/* Receiver */
if (!first) {
pthread_mutex_lock(&syncmutex[par->num]);
first = 1;
}
pthread_mutex_lock(&testmutex[par->num]);
/* ... Got the lock: End of latency measurement */
gettimeofday(&par->received, NULL);
par->samples++;
timersub(&par->received, &par->neighbor->unblocked,
&par->diff);
if (par->diff.tv_usec < par->mindiff)
par->mindiff = par->diff.tv_usec;
if (par->diff.tv_usec > par->maxdiff)
par->maxdiff = par->diff.tv_usec;
par->sumdiff += (double) par->diff.tv_usec;
if (par->tracelimit && par->maxdiff > par->tracelimit) {
char tracing_enabled_file[MAX_PATH];
strcpy(tracing_enabled_file, get_debugfileprefix());
strcat(tracing_enabled_file, "tracing_enabled");
int tracing_enabled =
open(tracing_enabled_file, O_WRONLY);
if (tracing_enabled >= 0) {
write(tracing_enabled, "0", 1);
close(tracing_enabled);
} else
snprintf(par->error, sizeof(par->error),
"Could not access %s\n",
tracing_enabled_file);
par->shutdown = 1;
par->neighbor->shutdown = 1;
}
if (par->max_cycles && par->samples >= par->max_cycles)
par->shutdown = 1;
if (mustgetcpu) {
par->cpu = sched_getcpu();
}
nanosleep(&par->delay, NULL);
pthread_mutex_unlock(&syncmutex[par->num]);
}
}
par->stopped = 1;
return NULL;
}
static void display_help(void)
{
printf("ptsematest V %1.2f\n", VERSION_STRING);
puts("Usage: ptsematest <options>");
puts("Function: test POSIX threads mutex latency");
puts(
"Options:\n"
"-a [NUM] --affinity run thread #N on processor #N, if possible\n"
" with NUM pin all threads to the processor NUM\n"
"-b USEC --breaktrace=USEC send break trace command when latency > USEC\n"
"-d DIST --distance=DIST distance of thread intervals in us default=500\n"
"-i INTV --interval=INTV base interval of thread in us default=1000\n"
"-l LOOPS --loops=LOOPS number of loops: default=0(endless)\n"
"-p PRIO --prio=PRIO priority\n"
"-t --threads one thread per available processor\n"
"-t [NUM] --threads=NUM number of threads:\n"
" without NUM, threads = max_cpus\n"
" without -t default = 1\n");
exit(1);
}
static int setaffinity = AFFINITY_UNSPECIFIED;
static int affinity;
static int tracelimit;
static int priority;
static int num_threads = 1;
static int max_cycles;
static int interval = 1000;
static int distance = 500;
static void process_options (int argc, char *argv[])
{
int error = 0;
int max_cpus = sysconf(_SC_NPROCESSORS_CONF);
for (;;) {
int option_index = 0;
/** Options for getopt */
static struct option long_options[] = {
{"affinity", optional_argument, NULL, 'a'},
{"breaktrace", required_argument, NULL, 'b'},
{"distance", required_argument, NULL, 'd'},
{"interval", required_argument, NULL, 'i'},
{"loops", required_argument, NULL, 'l'},
{"priority", required_argument, NULL, 'p'},
{"threads", optional_argument, NULL, 't'},
{"help", no_argument, NULL, '?'},
{NULL, 0, NULL, 0}
};
int c = getopt_long (argc, argv, "a::b:d:i:l:p:t::",
long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 'a':
if (optarg != NULL) {
affinity = atoi(optarg);
setaffinity = AFFINITY_SPECIFIED;
} else if (optind<argc && atoi(argv[optind])) {
affinity = atoi(argv[optind]);
setaffinity = AFFINITY_SPECIFIED;
} else {
setaffinity = AFFINITY_USEALL;
}
break;
case 'b': tracelimit = atoi(optarg); break;
case 'd': distance = atoi(optarg); break;
case 'i': interval = atoi(optarg); break;
case 'l': max_cycles = atoi(optarg); break;
case 'p': priority = atoi(optarg); break;
case 't':
if (optarg != NULL)
num_threads = atoi(optarg);
else if (optind<argc && atoi(argv[optind]))
num_threads = atoi(argv[optind]);
else
num_threads = max_cpus;
break;
case '?': error = 1; break;
}
}
if (setaffinity == AFFINITY_SPECIFIED) {
if (affinity < 0)
error = 1;
if (affinity >= max_cpus) {
fprintf(stderr, "ERROR: CPU #%d not found, only %d CPUs available\n",
affinity, max_cpus);
error = 1;
}
}
if (num_threads < 0 || num_threads > 255)
error = 1;
if (priority < 0 || priority > 99)
error = 1;
if (num_threads < 1)
error = 1;
if (error)
display_help ();
}
static int volatile shutdown;
static void sighand(int sig)
{
shutdown = 1;
}
int main(int argc, char *argv[])
{
int i;
int max_cpus = sysconf(_SC_NPROCESSORS_CONF);
int oldsamples = 1;
struct params *receiver = NULL;
struct params *sender = NULL;
sigset_t sigset;
struct timespec maindelay;
process_options(argc, argv);
if (check_privs())
return 1;
if (mlockall(MCL_CURRENT|MCL_FUTURE) == -1) {
perror("mlockall");
return 1;
}
signal(SIGINT, sighand);
signal(SIGTERM, sighand);
receiver = calloc(num_threads, sizeof(struct params));
sender = calloc(num_threads, sizeof(struct params));
if (receiver == NULL || sender == NULL)
goto nomem;
testmutex = (pthread_mutex_t *) calloc(num_threads, sizeof(pthread_mutex_t));
syncmutex = (pthread_mutex_t *) calloc(num_threads, sizeof(pthread_mutex_t));
if (testmutex == NULL || syncmutex == NULL)
goto nomem;
for (i = 0; i < num_threads; i++) {
receiver[i].mindiff = UINT_MAX;
receiver[i].maxdiff = 0;
receiver[i].sumdiff = 0.0;
pthread_mutex_init(&testmutex[i], NULL);
pthread_mutex_init(&syncmutex[i], NULL);
/* Wait on first attempt */
pthread_mutex_lock(&testmutex[i]);
receiver[i].num = i;
receiver[i].cpu = i;
switch (setaffinity) {
case AFFINITY_UNSPECIFIED: receiver[i].cpu = -1; break;
case AFFINITY_SPECIFIED: receiver[i].cpu = affinity; break;
case AFFINITY_USEALL: receiver[i].cpu = i % max_cpus; break;
}
receiver[i].priority = priority;
receiver[i].tracelimit = tracelimit;
if (priority > 0)
priority--;
receiver[i].delay.tv_sec = interval / USEC_PER_SEC;
receiver[i].delay.tv_nsec = (interval % USEC_PER_SEC) * 1000;
interval += distance;
receiver[i].max_cycles = max_cycles;
receiver[i].sender = 0;
receiver[i].neighbor = &sender[i];
pthread_create(&receiver[i].threadid, NULL, semathread, &receiver[i]);
memcpy(&sender[i], &receiver[i], sizeof(receiver[0]));
sender[i].sender = 1;
sender[i].neighbor = &receiver[i];
pthread_create(&sender[i].threadid, NULL, semathread, &sender[i]);
}
maindelay.tv_sec = 0;
maindelay.tv_nsec = 50000000; /* 50 ms */
while (!shutdown) {
int printed;
int errorlines = 0;
for (i = 0; i < num_threads; i++)
shutdown |= receiver[i].shutdown | sender[i].shutdown;
if (receiver[0].samples > oldsamples || shutdown) {
for (i = 0; i < num_threads; i++) {
printf("#%1d: ID%d, P%d, CPU%d, I%ld; #%1d: ID%d, P%d, CPU%d, Cycles %d\n",
i*2, receiver[i].tid, receiver[i].priority, receiver[i].cpu,
receiver[i].delay.tv_nsec / 1000,
i*2+1, sender[i].tid, sender[i].priority, sender[i].cpu,
sender[i].samples);
}
for (i = 0; i < num_threads; i++) {
printf("#%d -> #%d, Min %4d, Cur %4d, Avg %4d, Max %4d\n",
i*2+1, i*2,
receiver[i].mindiff, (int) receiver[i].diff.tv_usec,
(int) ((receiver[i].sumdiff / receiver[i].samples) + 0.5),
receiver[i].maxdiff);
if (receiver[i].error[0] != '\0') {
printf(receiver[i].error);
errorlines++;
receiver[i].error[0] = '\0';
}
if (sender[i].error[0] != '\0') {
printf(sender[i].error);
errorlines++;
receiver[i].error[0] = '\0';
}
}
printed = 1;
} else
printed = 0;
sigemptyset(&sigset);
sigaddset(&sigset, SIGTERM);
sigaddset(&sigset, SIGINT);
pthread_sigmask(SIG_SETMASK, &sigset, NULL);
nanosleep(&maindelay, NULL);
sigemptyset(&sigset);
pthread_sigmask(SIG_SETMASK, &sigset, NULL);
if (printed && !shutdown)
printf("\033[%dA", num_threads*2 + errorlines);
}
for (i = 0; i < num_threads; i++) {
receiver[i].shutdown = 1;
sender[i].shutdown = 1;
pthread_mutex_unlock(&testmutex[i]);
pthread_mutex_unlock(&syncmutex[i]);
}
nanosleep(&receiver[0].delay, NULL);
for (i = 0; i < num_threads; i++) {
if (!receiver[i].stopped)
pthread_kill(receiver[i].threadid, SIGTERM);
if (!sender[i].stopped)
pthread_kill(sender[i].threadid, SIGTERM);
}
for (i = 0; i < num_threads; i++) {
pthread_mutex_destroy(&testmutex[i]);
pthread_mutex_destroy(&syncmutex[i]);
}
nomem:
return 0;
}

View File

@ -1,17 +1,17 @@
CFLAGS += -Wall -O2
LDFLAGS += -lpthread -lrt
all: sigwaittest
@echo Done
sigwaittest.o: sigwaittest.c
sigwaittest:
clean:
@rm -f *.o
tar: clean
@rm -f sigwaittest
$(shell bn=`basename $$PWD`; cd ..; tar -zcf $$bn.tgz $$bn)
CFLAGS += -Wall -O2
LDFLAGS += -lpthread -lrt
all: sigwaittest
@echo Done
sigwaittest.o: sigwaittest.c
sigwaittest:
clean:
@rm -f *.o
tar: clean
@rm -f sigwaittest
$(shell bn=`basename $$PWD`; cd ..; tar -zcf $$bn.tgz $$bn)

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,16 @@
CFLAGS += -Wall -O2
LDFLAGS += -lpthread -lrt
all: svsematest
@echo Done
svsematest.o: svsematest.c
svsematest:
clean:
@rm -f *.o
tar: clean
@rm -f svsematest
$(shell bn=`basename $$PWD`; cd ..; tar -zcf $$bn.tgz $$bn)
CFLAGS += -Wall -O2
LDFLAGS += -lpthread -lrt
all: svsematest
@echo Done
svsematest.o: svsematest.c
svsematest:
clean:
@rm -f *.o
tar: clean
@rm -f svsematest
$(shell bn=`basename $$PWD`; cd ..; tar -zcf $$bn.tgz $$bn)

File diff suppressed because it is too large Load Diff