Initial Spring 2016 commit.

This commit is contained in:
Geoffrey Challen
2015-12-23 00:50:04 +00:00
commit cafa9f5690
732 changed files with 92195 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
# Makefile for schedpong
TOP=../../..
.include "$(TOP)/mk/os161.config.mk"
PROG=schedpong
SRCS=main.c think.c grind.c pong.c results.c usem.c
BINDIR=/testbin
.include "$(TOP)/mk/os161.prog.mk"

View File

@@ -0,0 +1,205 @@
/*
* Copyright (c) 2015
* The President and Fellows of Harvard College.
* Written by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#include <errno.h>
#include "tasks.h"
#define RIGHT 184621353
/*
* comparison functions for qsort
*/
static
int
uintcmp(const void *av, const void *bv)
{
unsigned a = *(const unsigned *)av;
unsigned b = *(const unsigned *)bv;
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
}
static
int
altcmp(const void *av, const void *bv)
{
unsigned a = *(const unsigned *)av;
unsigned b = *(const unsigned *)bv;
unsigned ax = (a & 0xffff0000) >> 16;
unsigned ay = a & 0xffff;
unsigned bx = (b & 0xffff0000) >> 16;
unsigned by = b & 0xffff;
if (ax < bx) {
return 1;
}
if (ax > bx) {
return -1;
}
if (ay < by) {
return -1;
}
if (ay > by) {
return 1;
}
return 0;
}
#if 0
/*
* Shuffle an array.
*/
static
void
shuffle(unsigned *p, unsigned n)
{
unsigned i, x, t;
for (i=0; i<n; i++) {
x = i + random() % (n-i);
t = p[i];
p[i] = p[x];
p[x] = t;
}
}
#endif
/*
* Compute first differences.
*/
static
void
diffs(unsigned *p, unsigned n)
{
unsigned p0;
unsigned i;
p0 = p[0];
for (i=0; i<n-1; i++) {
p[i] = p[i] - p[i+1];
}
p[n-1] = p[n-1] - p0;
}
/*
* Take the sum.
*/
static
unsigned
sum(const unsigned *p, unsigned n)
{
unsigned t, i;
t = 0;
for (i=0; i<n; i++) {
t += p[i];
}
return t;
}
/*
* grind - memory-bound task
*
* Note that this won't work until you have a VM system.
*/
void
grind(unsigned groupid, unsigned id)
{
unsigned *p;
unsigned i, n, s;
(void)groupid;
waitstart();
/* each grind task uses 768K */
n = (768*1024) / sizeof(*p);
p = malloc(n * sizeof(*p));
if (p == NULL) {
if (errno == ENOSYS) {
/*
* If we don't have sbrk, just bail out with
* "success" instead of failing the whole
* workload.
*/
errx(0, "grind: sbrk/malloc not implemented");
}
err(1, "malloc");
}
/* First, get some random integers. */
warnx("grind %u: seeding", id);
srandom(1753);
for (i=0; i<n; i++) {
p[i] = random();
}
/* Now sort them. */
warnx("grind %u: sorting", id);
qsort(p, n, sizeof(p[0]), uintcmp);
/* Sort by a different comparison. */
warnx("grind %u: sorting alternately", id);
qsort(p, n, sizeof(p[0]), altcmp);
/* Take the sum. */
warnx("grind %u: summing", id);
s = sum(p, n);
warnx("grind %u: sum is %u (should be %u)", id, s, RIGHT);
if (s != RIGHT) {
errx(1, "grind %u FAILED", id);
}
/* Take first differences. */
warnx("grind %u: first differences", id);
diffs(p, n);
/* Sort. */
warnx("grind %u: sorting", id);
qsort(p, n, sizeof(p[0]), uintcmp);
warnx("grind %u: summing", id);
s = sum(p, n);
warnx("grind %u: sum is %u (should be 0)", id, s);
if (s != 0) {
errx(1, "grind %u FAILED", id);
}
}

View File

@@ -0,0 +1,319 @@
/*
* Copyright (c) 2015
* The President and Fellows of Harvard College.
* Written by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/wait.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <err.h>
#include "usem.h"
#include "tasks.h"
#include "results.h"
#define STARTSEM "sem:start"
struct usem startsem;
/*
* Task hook function that does nothing.
*/
static
void
nop(unsigned groupid, unsigned count)
{
(void)groupid;
(void)count;
}
/*
* Wrapper for wait.
*/
static
unsigned
dowait(pid_t pid)
{
int r;
int status;
r = waitpid(pid, &status, 0);
if (r < 0) {
err(1, "waitpid");
}
if (WIFSIGNALED(status)) {
warnx("pid %d signal %d", pid, WTERMSIG(status));
return 1;
}
if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
warnx("pid %d exit %d", pid, WEXITSTATUS(status));
return 1;
}
return 0;
}
/*
* Do a task group: fork the processes, then wait for them.
*/
static
void
runtaskgroup(unsigned count,
void (*prep)(unsigned, unsigned),
void (*task)(unsigned, unsigned),
void (*cleanup)(unsigned, unsigned),
unsigned groupid)
{
pid_t mypids[count];
unsigned i;
unsigned failures = 0;
time_t secs;
unsigned long nsecs;
prep(groupid, count);
for (i=0; i<count; i++) {
mypids[i] = fork();
if (mypids[i] < 0) {
err(1, "fork");
}
if (mypids[i] == 0) {
/* child (of second fork) */
task(groupid, i);
exit(0);
}
/* parent (of second fork) - continue */
}
/*
* now wait for the task to finish
*/
for (i=0; i<count; i++) {
failures += dowait(mypids[i]);
}
/*
* Store the end time.
*/
__time(&secs, &nsecs);
openresultsfile(O_WRONLY);
putresult(groupid, secs, nsecs);
closeresultsfile();
cleanup(groupid, count);
exit(failures ? 1 : 0);
}
/*
* Fork the task groups. We will two tiers of fork: fork once to get a
* process to own the task group, and then within the task group again
* N times to get the processes to do the task. This way we can wait
* for the different collections of task processes independently and
* get timing results even on kernels that don't support waitpid with
* WNOHANG.
*/
static
void
forkem(unsigned count,
void (*prep)(unsigned, unsigned),
void (*task)(unsigned, unsigned),
void (*cleanup)(unsigned, unsigned),
unsigned groupid,
pid_t *retpid)
{
*retpid = fork();
if (*retpid < 0) {
err(1, "fork");
}
if (*retpid == 0) {
/* child */
runtaskgroup(count, prep, task, cleanup, groupid);
}
/* parent -- just return */
}
/*
* Wait for the task group directors to exit.
*/
static
void
waitall(pid_t *pids, unsigned numpids)
{
unsigned failures = 0;
unsigned i;
for (i=0; i<numpids; i++) {
failures += dowait(pids[i]);
}
if (failures) {
errx(1, "TEST FAILURE: one or more subprocesses broke");
}
}
/*
* Fetch, compute, and print the timing for one task group.
*/
static
void
calcresult(unsigned groupid, time_t startsecs, unsigned long startnsecs,
char *buf, size_t bufmax)
{
time_t secs;
unsigned long nsecs;
getresult(groupid, &secs, &nsecs);
/* secs.nsecs -= startsecs.startnsecs */
if (nsecs < startnsecs) {
nsecs += 1000000000;
secs--;
}
nsecs -= startnsecs;
secs -= startsecs;
snprintf(buf, bufmax, "%lld.%09lu", (long long)secs, nsecs);
}
/*
* Used by the tasks to wait to start.
*/
void
waitstart(void)
{
usem_open(&startsem);
P(&startsem);
usem_close(&startsem);
}
/*
* Run the whole workload.
*/
static
void
runit(unsigned numthinkers, unsigned numgrinders,
unsigned numponggroups, unsigned ponggroupsize)
{
pid_t pids[numponggroups + 2];
time_t startsecs;
unsigned long startnsecs;
char buf[32];
unsigned i;
printf("Running with %u thinkers, %u grinders, and %u pong groups "
"of size %u each.\n", numthinkers, numgrinders, numponggroups,
ponggroupsize);
usem_init(&startsem, STARTSEM);
createresultsfile();
forkem(numthinkers, nop, think, nop, 0, &pids[0]);
forkem(numgrinders, nop, grind, nop, 1, &pids[1]);
for (i=0; i<numponggroups; i++) {
forkem(ponggroupsize, pong_prep, pong, pong_cleanup, i+2,
&pids[i+2]);
}
usem_open(&startsem);
printf("Forking done; starting the workload.\n");
__time(&startsecs, &startnsecs);
Vn(&startsem, numthinkers + numgrinders +
numponggroups * ponggroupsize);
waitall(pids, numponggroups + 2);
usem_close(&startsem);
usem_cleanup(&startsem);
openresultsfile(O_RDONLY);
printf("--- Timings ---\n");
if (numthinkers > 0) {
calcresult(0, startsecs, startnsecs, buf, sizeof(buf));
printf("Thinkers: %s\n", buf);
}
if (numgrinders > 0) {
calcresult(1, startsecs, startnsecs, buf, sizeof(buf));
printf("Grinders: %s\n", buf);
}
for (i=0; i<numponggroups; i++) {
calcresult(i+2, startsecs, startnsecs, buf, sizeof(buf));
printf("Pong group %u: %s\n", i, buf);
}
closeresultsfile();
destroyresultsfile();
}
static
void
usage(const char *av0)
{
warnx("Usage: %s [options]", av0);
warnx(" [-t thinkers] set number of thinkers (default 2)");
warnx(" [-g grinders] set number of grinders (default 0)");
warnx(" [-p ponggroups] set number of pong groups (default 1)");
warnx(" [-s ponggroupsize] set pong group size (default 6)");
warnx("Thinkers are CPU bound; grinders are memory-bound;");
warnx("pong groups are I/O bound.");
exit(1);
}
int
main(int argc, char *argv[])
{
unsigned numthinkers = 2;
unsigned numgrinders = 0;
unsigned numponggroups = 1;
unsigned ponggroupsize = 6;
int i;
for (i=1; i<argc; i++) {
if (!strcmp(argv[i], "-t")) {
numthinkers = atoi(argv[++i]);
}
else if (!strcmp(argv[i], "-g")) {
numgrinders = atoi(argv[++i]);
}
else if (!strcmp(argv[i], "-p")) {
numponggroups = atoi(argv[++i]);
}
else if (!strcmp(argv[i], "-s")) {
ponggroupsize = atoi(argv[++i]);
}
else {
usage(argv[0]);
}
}
runit(numthinkers, numgrinders, numponggroups, ponggroupsize);
return 0;
}

View File

@@ -0,0 +1,211 @@
/*
* Copyright (c) 2015
* The President and Fellows of Harvard College.
* Written by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Semaphore pong.
*/
#include <stdio.h>
#include <err.h>
#include <assert.h>
#include "usem.h"
#include "tasks.h"
#define MAXCOUNT 64
#define PONGLOOPS 1000
//#define VERBOSE_PONG
static struct usem sems[MAXCOUNT];
static unsigned nsems;
/*
* Set up the semaphores. This happens in the task director process,
* so if we have multiple pong groups each has its own sems[] array.
* (at least if the VM works)
*
* Note that we don't open the semaphores in the director process;
* that way each task process has its own file handles and they don't
* interfere with each other if file handle locking isn't so great.
*/
void
pong_prep(unsigned groupid, unsigned count)
{
unsigned i;
if (count > MAXCOUNT) {
err(1, "pong: too many pongers -- recompile pong.c");
}
for (i=0; i<count; i++) {
usem_init(&sems[i], "sem:pong-%u-%u", groupid, i);
}
nsems = count;
}
void
pong_cleanup(unsigned groupid, unsigned count)
{
unsigned i;
assert(nsems == count);
(void)groupid;
for (i=0; i<count; i++) {
usem_cleanup(&sems[i]);
}
}
/*
* Pong in order. Wait on our semaphore, then wake the next one.
* If we're id 0, don't wait the first go so things start, but do
* wait the last go.
*/
static
void
pong_cyclic(unsigned id)
{
unsigned i;
unsigned nextid;
nextid = (id + 1) % nsems;
for (i=0; i<PONGLOOPS; i++) {
if (i > 0 || id > 0) {
P(&sems[id]);
}
#ifdef VERBOSE_PONG
printf(" %u", id);
#else
if (nextid == 0 && i % 16 == 0) {
putchar('.');
}
#endif
V(&sems[nextid]);
}
if (id == 0) {
P(&sems[id]);
}
#ifdef VERBOSE_PONG
putchar('\n');
#else
if (nextid == 0) {
putchar('\n');
}
#endif
}
/*
* Pong back and forth. This runs the tasks with middle numbers more
* often.
*/
static
void
pong_reciprocating(unsigned id)
{
unsigned i, n;
unsigned nextfwd, nextback;
unsigned gofwd = 1;
if (id == 0) {
nextfwd = nextback = 1;
n = PONGLOOPS;
}
else if (id == nsems - 1) {
nextfwd = nextback = nsems - 2;
n = PONGLOOPS;
}
else {
nextfwd = id + 1;
nextback = id - 1;
n = PONGLOOPS * 2;
}
for (i=0; i<n; i++) {
if (i > 0 || id > 0) {
P(&sems[id]);
}
#ifdef VERBOSE_PONG
printf(" %u", id);
#else
if (id == 0 && i % 16 == 0) {
putchar('.');
}
#endif
if (gofwd) {
V(&sems[nextfwd]);
gofwd = 0;
}
else {
V(&sems[nextback]);
gofwd = 1;
}
}
if (id == 0) {
P(&sems[id]);
}
#ifdef VERBOSE_PONG
putchar('\n');
#else
if (id == 0) {
putchar('\n');
}
#endif
}
/*
* Do the pong thing.
*/
void
pong(unsigned groupid, unsigned id)
{
unsigned idfwd, idback;
(void)groupid;
idfwd = (id + 1) % nsems;
idback = (id + nsems - 1) % nsems;
usem_open(&sems[id]);
usem_open(&sems[idfwd]);
usem_open(&sems[idback]);
waitstart();
pong_cyclic(id);
#ifdef VERBOSE_PONG
printf("--------------------------------\n");
#endif
pong_reciprocating(id);
#ifdef VERBOSE_PONG
printf("--------------------------------\n");
#endif
pong_cyclic(id);
usem_close(&sems[id]);
usem_close(&sems[idfwd]);
usem_close(&sems[idback]);
}

View File

@@ -0,0 +1,169 @@
/*
* Copyright (c) 2015
* The President and Fellows of Harvard College.
* Written by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <unistd.h>
#include <fcntl.h>
#include <err.h>
#include <errno.h>
#include <assert.h>
#include "results.h"
#define RESULTSFILE "endtimes"
static int resultsfile = -1;
/*
* Create the file that the timing results are written to.
* This is done first, in the main process.
*/
void
createresultsfile(void)
{
int fd;
assert(resultsfile == -1);
fd = open(RESULTSFILE, O_RDWR|O_CREAT|O_TRUNC, 0664);
if (fd < 0) {
err(1, "%s", RESULTSFILE);
}
if (close(fd) == -1) {
warn("%s: close", RESULTSFILE);
}
}
/*
* Remove the timing results file.
* This is done last, in the main process.
*/
void
destroyresultsfile(void)
{
if (remove(RESULTSFILE) == -1) {
if (errno != ENOSYS) {
warn("%s: remove", RESULTSFILE);
}
}
}
/*
* Open the timing results file. This is done separately for writing
* in each process to avoid sharing the seek position (which would
* then require extra semaphoring to coordinate...) and afterwards
* done for reading in the main process.
*/
void
openresultsfile(int openflags)
{
assert(openflags == O_RDONLY || openflags == O_WRONLY);
assert(resultsfile == -1);
resultsfile = open(RESULTSFILE, openflags, 0);
if (resultsfile < 0) {
err(1, "%s", RESULTSFILE);
}
}
/*
* Close the timing results file.
*/
void
closeresultsfile(void)
{
assert(resultsfile >= 0);
if (close(resultsfile) == -1) {
warn("%s: close", RESULTSFILE);
}
resultsfile = -1;
}
/*
* Write a result into the timing results file.
*/
void
putresult(unsigned groupid, time_t secs, unsigned long nsecs)
{
off_t pos;
ssize_t r;
assert(resultsfile >= 0);
pos = groupid * (sizeof(secs) + sizeof(nsecs));
if (lseek(resultsfile, pos, SEEK_SET) == -1) {
err(1, "%s: lseek", RESULTSFILE);
}
r = write(resultsfile, &secs, sizeof(secs));
if (r < 0) {
err(1, "%s: write (seconds)", RESULTSFILE);
}
if ((size_t)r < sizeof(secs)) {
errx(1, "%s: write (seconds): Short write", RESULTSFILE);
}
r = write(resultsfile, &nsecs, sizeof(nsecs));
if (r < 0) {
err(1, "%s: write (nsecs)", RESULTSFILE);
}
if ((size_t)r < sizeof(nsecs)) {
errx(1, "%s: write (nsecs): Short write", RESULTSFILE);
}
}
/*
* Read a result from the timing results file.
*/
void
getresult(unsigned groupid, time_t *secs, unsigned long *nsecs)
{
off_t pos;
ssize_t r;
assert(resultsfile >= 0);
pos = groupid * (sizeof(*secs) + sizeof(*nsecs));
if (lseek(resultsfile, pos, SEEK_SET) == -1) {
err(1, "%s: lseek", RESULTSFILE);
}
r = read(resultsfile, secs, sizeof(*secs));
if (r < 0) {
err(1, "%s: read (seconds)", RESULTSFILE);
}
if ((size_t)r < sizeof(*secs)) {
errx(1, "%s: read (seconds): Unexpected EOF", RESULTSFILE);
}
r = read(resultsfile, nsecs, sizeof(*nsecs));
if (r < 0) {
err(1, "%s: read (nsecs)", RESULTSFILE);
}
if ((size_t)r < sizeof(*nsecs)) {
errx(1, "%s: read (nsecs): Unexpected EOF", RESULTSFILE);
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2015
* The President and Fellows of Harvard College.
* Written by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
void createresultsfile(void);
void destroyresultsfile(void);
void openresultsfile(int openflags);
void closeresultsfile(void);
void putresult(unsigned groupid, time_t secs, unsigned long nsecs);
void getresult(unsigned groupid, time_t *secs, unsigned long *nsecs);

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2015
* The President and Fellows of Harvard College.
* Written by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
void waitstart(void);
void think(unsigned groupid, unsigned id);
void grind(unsigned groupid, unsigned id);
void pong_prep(unsigned groupid, unsigned count);
void pong_cleanup(unsigned groupid, unsigned count);
void pong(unsigned groupid, unsigned id);

View File

@@ -0,0 +1,55 @@
/*
* Copyright (c) 2015
* The President and Fellows of Harvard College.
* Written by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "tasks.h"
/*
* think - cpu-bound task
*
* All we do is loop.
*/
void
think(unsigned groupid, unsigned id)
{
volatile unsigned long k, m;
volatile unsigned i;
(void)groupid;
(void)id;
waitstart();
k = 15;
m = 7;
#define LOOPCOUNT 35000000
for (i=0; i<LOOPCOUNT; i++) {
k += k*m;
}
}

View File

@@ -0,0 +1,123 @@
/*
* Copyright (c) 2014, 2015
* The President and Fellows of Harvard College.
* Written by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* XXX this code is mostly copied from usemtest; it should go in a
* library.
*/
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <err.h>
#include "usem.h"
void
usem_init(struct usem *sem, const char *namefmt, ...)
{
va_list ap;
va_start(ap, namefmt);
vsnprintf(sem->name, sizeof(sem->name), namefmt, ap);
va_end(ap);
sem->fd = open(sem->name, O_RDWR|O_CREAT|O_TRUNC, 0664);
if (sem->fd < 0) {
err(1, "%s: create", sem->name);
}
close(sem->fd);
sem->fd = -1;
}
void
usem_open(struct usem *sem)
{
sem->fd = open(sem->name, O_RDWR);
if (sem->fd < 0) {
err(1, "%s: open", sem->name);
}
}
void
usem_close(struct usem *sem)
{
if (close(sem->fd) == -1) {
warn("%s: close", sem->name);
}
}
void
usem_cleanup(struct usem *sem)
{
(void)remove(sem->name);
}
void
Pn(struct usem *sem, unsigned count)
{
ssize_t r;
char c;
r = read(sem->fd, &c, count);
if (r < 0) {
err(1, "%s: read", sem->name);
}
if ((size_t)r < count) {
errx(1, "%s: read: unexpected EOF", sem->name);
}
}
void
P(struct usem *sem)
{
Pn(sem, 1);
}
void
Vn(struct usem *sem, unsigned count)
{
ssize_t r;
char c;
r = write(sem->fd, &c, count);
if (r < 0) {
err(1, "%s: write", sem->name);
}
if ((size_t)r < count) {
errx(1, "%s: write: Short count", sem->name);
}
}
void
V(struct usem *sem)
{
Vn(sem, 1);
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) 2015
* The President and Fellows of Harvard College.
* Written by David A. Holland.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Semaphore structure.
*/
struct usem {
char name[32];
int fd;
};
/* XXX this should be in sys/cdefs.h */
#if defined(__clang__) || defined(__GNUC__)
#define __PF(a, b) __attribute__((__format__(__printf__, a, b)))
#else
#define __PF(a, b)
#endif
__PF(2, 3) void usem_init(struct usem *sem, const char *namefmt, ...);
void usem_open(struct usem *sem);
void usem_close(struct usem *sem);
void usem_cleanup(struct usem *sem);
void Pn(struct usem *sem, unsigned count);
void P(struct usem *sem);
void Vn(struct usem *sem, unsigned count);
void V(struct usem *sem);