#define _GNU_SOURCE 1
#include
#include
Copyright By PowCoder代写 加微信 powcoder
#include
#include
#include
#include
#include
#include
#include
#include “threadpool_lib.h”
// http://www.guyrutenberg.com/2007/09/22/profiling-code-using-clock_gettime/
struct timespec timespec_diff(struct timespec start, struct timespec end)
struct timespec temp;
if ((end.tv_nsec-start.tv_nsec)<0) {
temp.tv_sec = end.tv_sec-start.tv_sec-1;
temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
temp.tv_sec = end.tv_sec-start.tv_sec;
temp.tv_nsec = end.tv_nsec-start.tv_nsec;
return temp;
void timespec_print(struct timespec ts, char *buf, size_t buflen)
snprintf(buf, buflen, "%lld.%.9ld", (long long)ts.tv_sec, ts.tv_nsec);
* Count number of threads by scanning /proc/self/status
* for the Threads: ... line
count_number_of_threads(void)
FILE * p = fopen("/proc/self/status", "r");
while (!feof(p)) {
int threadsleft;
char buf[128];
if (fgets(buf, sizeof buf, p) == NULL)
if (sscanf(buf, "Threads: %d\n", &threadsleft) != 1)
fclose(p);
return threadsleft;
printf("Internal error, please send email to
// int rc = getrusage(RUSAGE_CHILDREN, &usage);
// struct rusage {
// struct timeval ru_utime; /* user time used */
// struct timeval ru_stime; /* system time used */
// long ru_maxrss; /* maximum resident set size */
// long ru_ixrss; /* integral shared memory size */
// long ru_idrss; /* integral unshared data size */
// long ru_isrss; /* integral unshared stack size */
// long ru_minflt; /* page reclaims */
// long ru_majflt; /* page faults */
// long ru_nswap; /* swaps */
// long ru_inblock; /* block input operations */
// long ru_oublock; /* block output operations */
// long ru_msgsnd; /* messages sent */
// long ru_msgrcv; /* messages received */
// long ru_nsignals; /* signals received */
// long ru_nvcsw; /* voluntary context switches */
// long ru_nivcsw; /* involuntary context switches */
// };
static void print_rusage_as_json(FILE *output, struct rusage *usage)
fprintf(output, "\"ru_utime\" : %ld.%06ld, \"ru_stime\" : %ld.%06ld, \"ru_nvcsw\" : %ld, \"ru_nivcsw\" : %ld",
usage->ru_utime.tv_sec, usage->ru_utime.tv_usec,
usage->ru_stime.tv_sec, usage->ru_stime.tv_usec,
usage->ru_nvcsw, usage->ru_nivcsw
static void print_rusage_to_human(FILE *output, struct rusage *usage)
fprintf(output, “user time: %ld.%06lds\nsystem time: %ld.%06lds\n”,
usage->ru_utime.tv_sec, usage->ru_utime.tv_usec,
usage->ru_stime.tv_sec, usage->ru_stime.tv_usec
/* Compute the diff of interesting parameters in two rusage structs */
static void rusagesub(struct rusage *end, struct rusage *start, struct rusage *diff)
diff->ru_nvcsw = end->ru_nvcsw – start->ru_nvcsw;
diff->ru_nivcsw = end->ru_nivcsw – start->ru_nivcsw;
timersub(&end->ru_utime, &start->ru_utime, &diff->ru_utime);
timersub(&end->ru_stime, &start->ru_stime, &diff->ru_stime);
struct benchmark_data {
struct rusage rstart, rend, rdiff;
struct timeval start, end, diff;
struct benchmark_data * start_benchmark(void)
struct benchmark_data * bdata = malloc(sizeof *bdata);
int rc = getrusage(RUSAGE_SELF, &bdata->rstart);
if (rc == -1)
perror(“getrusage”);
gettimeofday(&bdata->start, NULL);
return bdata;
void stop_benchmark(struct benchmark_data * bdata)
gettimeofday(&bdata->end, NULL);
int rc = getrusage(RUSAGE_SELF, &bdata->rend);
if (rc == -1)
perror(“getrusage”);
rusagesub(&bdata->rend, &bdata->rstart, &bdata->rdiff);
timersub(&bdata->end, &bdata->start, &bdata->diff);
void report_benchmark_results(struct benchmark_data *bdata)
char buf[80];
snprintf(buf, sizeof buf, “runresult.%d.json”, getppid());
FILE * f = fopen(buf, “w”);
if (f == NULL) {
perror(“fopen”);
// fprintf(stderr, “Writing %s\n”, buf);
fprintf(f, “{“);
print_rusage_as_json(f, &bdata->rdiff);
fprintf(f, “, \”realtime\” : %ld.%06ld”, bdata->diff.tv_sec, bdata->diff.tv_usec);
fprintf(f, “}”);
fclose(f);
void report_benchmark_results_to_human(FILE *f, struct benchmark_data *bdata)
// fprintf(stderr, “Writing %s\n”, buf);
print_rusage_to_human(f, &bdata->rdiff);
fprintf(f, “real time: %ld.%06lds\n”, bdata->diff.tv_sec, bdata->diff.tv_usec);
/* FIXME: this code is Linux/64bit only. */
static void
catch_segfault(int signo, siginfo_t *info, void * _ctxt)
ucontext_t * ctxt = _ctxt;
uintptr_t faultaddr = (uintptr_t) info->si_addr;
uintptr_t rsp = (uintptr_t) ctxt->uc_mcontext.gregs[REG_RSP];
uintptr_t rip = (uintptr_t) ctxt->uc_mcontext.gregs[REG_RIP];
fprintf(stderr, “\n\n———————————————————————-\n\n”);
fprintf(stderr, “Segmentation Fault, faultaddr=0x%lx, rip=0x%lx, rsp=0x%lx\n”,
faultaddr, rip, rsp);
if (abs(faultaddr – rsp) < 2048) {
int page_size = 4096;
pthread_attr_t attr;
void * stackaddr;
size_t stacksize;
pthread_getattr_np(pthread_self(), &attr); // non portable
pthread_attr_getstack( &attr, &stackaddr, &stacksize );
stackaddr += page_size; // subtract out guard page
stacksize -= page_size;
fprintf(stderr, "Likely stack overflow.\nThe current thread's stack bottom is at %p.\n", stackaddr);
fprintf(stderr, "Try using a larger stack size; read pthread_attr_setstacksize(3)\n");
fprintf(stderr, "Current thread stack size is %ld\n", stacksize);
fprintf(stderr, "Exiting now; the calling shell will not print 'Segmentation Fault'\n");
exit(EXIT_FAILURE);
* Fork/Join frameworks with child stealing may suffer from high stack
* consumption.
* Install a handler to detect stack overflow.
void install_stack_overflow_handler(void)
struct sigaction act;
#define ALT_STACK_SIZE 16*1024
stack_t ss = {
.ss_flags = 0,
.ss_sp = malloc(ALT_STACK_SIZE),
.ss_size = ALT_STACK_SIZE
if (sigaltstack(&ss, NULL)) {
perror ("sigaltstack");
exit (EXIT_FAILURE);
act.sa_sigaction = catch_segfault;
act.sa_flags = SA_SIGINFO | SA_ONSTACK;
sigemptyset (&act.sa_mask);
int status = sigaction (SIGSEGV, &act, NULL);
if (status) {
perror ("sigaction");
exit (EXIT_FAILURE);
程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com