Initial Spring 2016 commit.
This commit is contained in:
11
userland/testbin/schedpong/Makefile
Normal file
11
userland/testbin/schedpong/Makefile
Normal 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"
|
||||
|
205
userland/testbin/schedpong/grind.c
Normal file
205
userland/testbin/schedpong/grind.c
Normal 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);
|
||||
}
|
||||
}
|
319
userland/testbin/schedpong/main.c
Normal file
319
userland/testbin/schedpong/main.c
Normal 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;
|
||||
}
|
211
userland/testbin/schedpong/pong.c
Normal file
211
userland/testbin/schedpong/pong.c
Normal 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]);
|
||||
}
|
169
userland/testbin/schedpong/results.c
Normal file
169
userland/testbin/schedpong/results.c
Normal 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);
|
||||
}
|
||||
}
|
36
userland/testbin/schedpong/results.h
Normal file
36
userland/testbin/schedpong/results.h
Normal 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);
|
38
userland/testbin/schedpong/tasks.h
Normal file
38
userland/testbin/schedpong/tasks.h
Normal 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);
|
55
userland/testbin/schedpong/think.c
Normal file
55
userland/testbin/schedpong/think.c
Normal 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;
|
||||
}
|
||||
}
|
123
userland/testbin/schedpong/usem.c
Normal file
123
userland/testbin/schedpong/usem.c
Normal 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);
|
||||
}
|
53
userland/testbin/schedpong/usem.h
Normal file
53
userland/testbin/schedpong/usem.h
Normal 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);
|
Reference in New Issue
Block a user