diff options
Diffstat (limited to 'gcell')
137 files changed, 12873 insertions, 0 deletions
diff --git a/gcell/Makefile.am b/gcell/Makefile.am new file mode 100644 index 000000000..959d3563d --- /dev/null +++ b/gcell/Makefile.am @@ -0,0 +1,26 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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 3, or (at your option) +# any later version. +# +# GNU Radio 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +include $(top_srcdir)/Makefile.common + +SUBDIRS = src + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = diff --git a/gcell/gcell.pc.in b/gcell/gcell.pc.in new file mode 100644 index 000000000..2b6101d13 --- /dev/null +++ b/gcell/gcell.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: gcell +Description: The GNU Radio SPE scheduler and RPC mechanism +Requires: gnuradio-omnithread mblock +Version: @VERSION@ +Libs: -L${libdir} -lgcell +Cflags: -I${includedir} @DEFINES@ diff --git a/gcell/src/Makefile.am b/gcell/src/Makefile.am new file mode 100644 index 000000000..af76eb67e --- /dev/null +++ b/gcell/src/Makefile.am @@ -0,0 +1,23 @@ +# +# Copyright 2007,2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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 3, or (at your option) +# any later version. +# +# GNU Radio 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +include $(top_srcdir)/Makefile.common + +SUBDIRS = include lib apps ibm diff --git a/gcell/src/apps/Makefile.am b/gcell/src/apps/Makefile.am new file mode 100644 index 000000000..e8cbf3cfc --- /dev/null +++ b/gcell/src/apps/Makefile.am @@ -0,0 +1,47 @@ +# +# Copyright 2007,2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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 3, or (at your option) +# any later version. +# +# GNU Radio 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +include $(top_srcdir)/Makefile.common + +SUBDIRS = spu . + +AM_CPPFLAGS = $(DEFINES) $(OMNITHREAD_INCLUDES) $(MBLOCK_INCLUDES) \ + $(GCELL_INCLUDES) $(CPPUNIT_INCLUDES) $(WITH_INCLUDES) + + +GCELL_QA_LA = $(top_builddir)/gcell/src/lib/libgcell-qa.la + +TESTS = test_all + + +bin_PROGRAMS = \ + test_all \ + benchmark_dma \ + benchmark_nop + + +test_all_SOURCES = test_all.cc +test_all_LDADD = $(GCELL_QA_LA) $(GCELL_LA) + +benchmark_dma_SOURCES = benchmark_dma.cc +benchmark_dma_LDADD = spu/benchmark_procs $(GCELL_LA) $(MBLOCK_LA) + +benchmark_nop_SOURCES = benchmark_nop.cc +benchmark_nop_LDADD = spu/benchmark_procs $(GCELL_LA) $(MBLOCK_LA) diff --git a/gcell/src/apps/benchmark_dma.cc b/gcell/src/apps/benchmark_dma.cc new file mode 100644 index 000000000..c3df3a91f --- /dev/null +++ b/gcell/src/apps/benchmark_dma.cc @@ -0,0 +1,265 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "gc_job_manager.h" +#include "mb_time.h" +#include <getopt.h> +#include <stdlib.h> +#include <stdio.h> +#include <boost/scoped_array.hpp> +#include <assert.h> + +// handle to embedded SPU executable that contains benchmark routines +// (The name of the variable (benchmark_procs) is the name of the spu executable.) +extern spe_program_handle_t benchmark_procs; + +static gc_proc_id_t gcp_benchmark_udelay = GCP_UNKNOWN_PROC; + +#define BENCHMARK_PUT 0x1 +#define BENCHMARK_GET 0x2 +#define BENCHMARK_GET_PUT (BENCHMARK_PUT|BENCHMARK_GET) + + +#if 0 +static bool +power_of_2_p(unsigned long x) +{ + int nbits = sizeof(x) * 8; + for (int i = 0; i < nbits; i++) + if (x == (1UL << i)) + return true; + + return false; +} +#endif + +static void +init_jd(gc_job_desc *jd, unsigned int usecs, + unsigned char *getbuf, unsigned char *putbuf, size_t buflen, + int getput_mask) +{ + jd->proc_id = gcp_benchmark_udelay; + jd->input.nargs = 1; + jd->input.arg[0].u32 = usecs; + jd->output.nargs = 0; + + switch(getput_mask & BENCHMARK_GET_PUT){ + + case BENCHMARK_GET: + jd->eaa.nargs = 1; + jd->eaa.arg[0].direction = GCJD_DMA_GET; + jd->eaa.arg[0].ea_addr = ptr_to_ea(getbuf); + jd->eaa.arg[0].get_size = buflen; + break; + + case BENCHMARK_PUT: + jd->eaa.nargs = 1; + jd->eaa.arg[0].direction = GCJD_DMA_PUT; + jd->eaa.arg[0].ea_addr = ptr_to_ea(putbuf); + jd->eaa.arg[0].put_size = buflen; + break; + + case BENCHMARK_GET_PUT: + jd->eaa.nargs = 2; + jd->eaa.arg[0].direction = GCJD_DMA_GET; + jd->eaa.arg[0].ea_addr = ptr_to_ea(getbuf); + jd->eaa.arg[0].get_size = buflen; + jd->eaa.arg[1].direction = GCJD_DMA_PUT; + jd->eaa.arg[1].ea_addr = ptr_to_ea(putbuf); + jd->eaa.arg[1].put_size = buflen; + break; + } +} + +static void +run_test(unsigned int nspes, unsigned int usecs, unsigned int dma_size, int getput_mask) +{ + static const int64_t TOTAL_SIZE_DMA = 5LL << 30; + static const int NJDS = 64; + unsigned int njobs = (unsigned int)(TOTAL_SIZE_DMA / dma_size); + //unsigned int njobs = NJDS * 16; + unsigned int nsubmitted = 0; + unsigned int ncompleted = 0; + gc_job_desc *all_jds[NJDS]; + gc_job_desc *jds[2][NJDS]; + unsigned int njds[2]; + unsigned int ci; // current index + bool done[NJDS]; + + static const unsigned int BUFSIZE = (32 << 10) * NJDS; + unsigned char *getbuf = new unsigned char[BUFSIZE]; + boost::scoped_array<unsigned char> _getbuf(getbuf); + unsigned char *putbuf = new unsigned char[BUFSIZE]; + boost::scoped_array<unsigned char> _putbuf(putbuf); + int gbi = 0; + + // touch all pages to force allocation now + for (unsigned int i = 0; i < BUFSIZE; i += 4096){ + getbuf[i] = 0; + putbuf[i] = 0; + } + + gc_jm_options opts; + opts.program_handle = &benchmark_procs; + opts.nspes = nspes; + //opts.enable_logging = true; + //opts.log2_nlog_entries = 13; + gc_job_manager *mgr = gc_make_job_manager(&opts); + + if ((gcp_benchmark_udelay = mgr->lookup_proc("benchmark_udelay")) == GCP_UNKNOWN_PROC){ + fprintf(stderr, "lookup_proc: failed to find \"benchmark_udelay\"\n"); + return; + } + + // allocate and init all job descriptors + for (int i = 0; i < NJDS; i++){ + if (gbi + dma_size > BUFSIZE) + gbi = 0; + + all_jds[i] = mgr->alloc_job_desc(); + init_jd(all_jds[i], usecs, &getbuf[gbi], &putbuf[gbi], dma_size, getput_mask); + gbi += dma_size; + } + + for (int iter = 0; iter < 1; iter++){ + + mb_time t_start = mb_time::time(); + + nsubmitted = 0; + ncompleted = 0; + + ci = 0; + njds[0] = 0; + njds[1] = 0; + + // submit the first batch + for (int i = 0; i < NJDS; i++){ + if (mgr->submit_job(all_jds[i])){ + jds[ci][njds[ci]++] = all_jds[i]; + nsubmitted++; + } + else { + printf("submit_job(jds[%d]) failed, status = %d\n", + i, all_jds[i]->status); + } + } + + while (ncompleted < njobs){ + njds[ci^1] = 0; + int n = mgr->wait_jobs(njds[ci], jds[ci], done, GC_WAIT_ANY); + // printf("%2d\n", n); + if (n < 0){ + fprintf(stderr, "mgr->wait_jobs failed\n"); + break; + } + for (unsigned int i = 0; i < njds[ci]; i++){ + if (!done[i]){ // remember for next iteration + jds[ci^1][njds[ci^1]++] = jds[ci][i]; + } + else { + ncompleted++; + // printf("ncompleted = %7d\n", ncompleted); + if (nsubmitted < njobs){ // submit another one + if (mgr->submit_job(jds[ci][i])){ + jds[ci^1][njds[ci^1]++] = jds[ci][i]; // remember for next iter + nsubmitted++; + } + else { + printf("submit_job(jds[%d]) failed, status = %d\n", + i, jds[ci][i]->status); + } + } + } + } + ci ^= 1; // toggle current + } + + // stop timing + mb_time t_stop = mb_time::time(); + + double delta = (t_stop - t_start).double_time(); + printf("nspes: %2d udelay: %4d elapsed_time: %7.3f dma_size: %5d dma_throughput: %7.3e\n", + mgr->nspes(), usecs, delta, dma_size, + (double) njobs * dma_size / delta * (getput_mask == BENCHMARK_GET_PUT ? 2.0 : 1.0)); + + } + + delete mgr; +} + +static void +usage() +{ + fprintf(stderr, "usage: benchmark_dma [-p] [-g] [-n <nspes>] [-u <udelay>] [-s <dma_size>]\n"); + fprintf(stderr, " you must specify one or both of -p (put) and -g (get)\n"); +} + + +int +main(int argc, char **argv) +{ + unsigned int nspes = 0; + unsigned int usecs = 0; + unsigned int dma_size = 32 << 10; + int getput_mask = 0; + int ch; + + while ((ch = getopt(argc, argv, "n:u:s:pg")) != EOF){ + switch(ch){ + case 'n': + nspes = strtol(optarg, 0, 0); + break; + + case 'u': + usecs = strtol(optarg, 0, 0); + break; + + case 's': + dma_size = strtol(optarg, 0, 0); + if (dma_size == 0){ + fprintf(stderr, "-s <dma_size> must be > 0\n"); + return 1; + } + break; + + case 'p': + getput_mask |= BENCHMARK_PUT; + break; + + case 'g': + getput_mask |= BENCHMARK_GET; + break; + + case '?': + default: + usage(); + return 1; + } + } + + if (getput_mask == 0){ + usage(); + return 1; + } + + run_test(nspes, usecs, dma_size, getput_mask); + return 0; +} diff --git a/gcell/src/apps/benchmark_nop.cc b/gcell/src/apps/benchmark_nop.cc new file mode 100644 index 000000000..7ef3f636e --- /dev/null +++ b/gcell/src/apps/benchmark_nop.cc @@ -0,0 +1,162 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "gc_job_manager.h" +#include "mb_time.h" +#include <getopt.h> +#include <stdlib.h> +#include <stdio.h> + +// handle to embedded SPU executable that contains benchmark routines +// (The name of the variable (benchmark_procs) is the name of the spu executable.) +extern spe_program_handle_t benchmark_procs; + +static gc_proc_id_t gcp_benchmark_udelay = GCP_UNKNOWN_PROC; + +static void +init_jd(gc_job_desc *jd, unsigned int usecs) +{ + jd->proc_id = gcp_benchmark_udelay; + jd->input.nargs = 1; + jd->input.arg[0].u32 = usecs; + jd->output.nargs = 0; + jd->eaa.nargs = 0; +} + +static void +run_test(unsigned int nspes, unsigned int usecs, int njobs) +{ + static const int NJDS = 64; + int nsubmitted = 0; + int ncompleted = 0; + gc_job_desc *all_jds[NJDS]; + gc_job_desc *jds[2][NJDS]; + unsigned int njds[2]; + unsigned int ci; // current index + bool done[NJDS]; + + gc_jm_options opts; + opts.program_handle = &benchmark_procs; + opts.nspes = nspes; + opts.gang_schedule = true; + gc_job_manager *mgr = gc_make_job_manager(&opts); + + if ((gcp_benchmark_udelay = mgr->lookup_proc("benchmark_udelay")) == GCP_UNKNOWN_PROC){ + fprintf(stderr, "lookup_proc: failed to find \"benchmark_udelay\"\n"); + return; + } + + // allocate and init all job descriptors + for (int i = 0; i < NJDS; i++){ + all_jds[i] = mgr->alloc_job_desc(); + init_jd(all_jds[i], usecs); + } + + mb_time t_start = mb_time::time(); + + ci = 0; + njds[0] = 0; + njds[1] = 0; + + // submit the first batch + for (int i = 0; i < NJDS; i++){ + if (mgr->submit_job(all_jds[i])){ + jds[ci][njds[ci]++] = all_jds[i]; + nsubmitted++; + } + else { + printf("submit_job(jds[%d]) failed, status = %d\n", + i, all_jds[i]->status); + } + } + + while (ncompleted < njobs){ + njds[ci^1] = 0; + int n = mgr->wait_jobs(njds[ci], jds[ci], done, GC_WAIT_ANY); + // printf("%2d\n", n); + if (n < 0){ + fprintf(stderr, "mgr->wait_jobs failed\n"); + break; + } + for (unsigned int i = 0; i < njds[ci]; i++){ + if (!done[i]){ // remember for next iteration + jds[ci^1][njds[ci^1]++] = jds[ci][i]; + } + else { + ncompleted++; + // printf("ncompleted = %7d\n", ncompleted); + if (nsubmitted < njobs){ // submit another one + if (mgr->submit_job(jds[ci][i])){ + jds[ci^1][njds[ci^1]++] = jds[ci][i]; // remember for next iter + nsubmitted++; + } + else { + printf("submit_job(jds[%d]) failed, status = %d\n", + i, jds[ci][i]->status); + } + } + } + } + ci ^= 1; // toggle current + } + + // stop timing + mb_time t_stop = mb_time::time(); + double delta = (t_stop - t_start).double_time(); + printf("nspes: %2d udelay: %4d elapsed_time: %7.3f njobs: %g speedup: %6.3f\n", + mgr->nspes(), usecs, delta, (double) njobs, + njobs * usecs * 1e-6 / delta); + + delete mgr; +} + +int +main(int argc, char **argv) +{ + unsigned int nspes = 0; + unsigned int usecs = 0; + int njobs = 500000; + int ch; + + while ((ch = getopt(argc, argv, "n:u:N:")) != EOF){ + switch(ch){ + case 'n': + nspes = strtol(optarg, 0, 0); + break; + + case 'u': + usecs = strtol(optarg, 0, 0); + break; + + case 'N': + njobs = strtol(optarg, 0, 0); + break; + + case '?': + default: + fprintf(stderr, "usage: benchmark_nop [-n <nspes>] [-u <udelay>] [-N <njobs>]\n"); + return 1; + } + } + + run_test(nspes, usecs, njobs); + return 0; +} diff --git a/gcell/src/apps/gen_script.py b/gcell/src/apps/gen_script.py new file mode 100755 index 000000000..e4bbc7480 --- /dev/null +++ b/gcell/src/apps/gen_script.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python + +import sys +import time +import os + +from optparse import OptionParser + + +def get_svn_rev(): + try: + f = os.popen("svn info", "r") + lines = f.readlines() + f.close() + except: + return "unk" + + svn_rev = "unk" + for l in lines: + if l.startswith('Revision:'): + t = l.rstrip() + svn_rev = t.split()[-1] + return svn_rev + +def is_ps3(): + try: + f = open("/proc/cpuinfo") + s = f.read() + except: + return False + + return s.find('PS3') != -1 + + +def main(): + + def make_fname(suffix): + return basename + '.' + suffix + + max_spes_default = 16 + if is_ps3(): + max_spes_default = 6 + + parser = OptionParser() + parser.add_option("-m", "--max-spes", type="int", default=max_spes_default, + metavar="NSPES", + help="maximum number of SPEs to use [default=%default]") + parser.add_option("", "--min-spes", type="int", default=1, + metavar="NSPES", + help="minimum number of SPEs to use [default=%default]") + parser.add_option("-p", "--oprofile", action="store_true", default=False, + help="emit oprofile commands") + parser.add_option("-t", "--tag", default=None, + help="additional goodie in generated filenames") + (options, args) = parser.parse_args() + if len(args) != 0: + parser.print_help() + sys.exit(1) + + svn_rev = get_svn_rev() + + os.environ['TZ'] = 'PST8PDT' # always pacific + time.tzset() + + tag = '' + if options.tag: + tag = '-' + options.tag + + basename = 'R-%s%s-%s' % (svn_rev, tag, time.strftime('%Y%m%d-%H%M')) + + base_njobs = int(500e3) + njobs = { + 1 : base_njobs, + 10 : base_njobs, + 50 : base_njobs, + 100 : base_njobs, + 200 : int(base_njobs/2), + 250 : int(base_njobs/2.5), + 300 : int(base_njobs/3), + 400 : int(base_njobs/4), + 500 : int(base_njobs/5) + } + + + f_results = make_fname('results') + f_opreport = make_fname('opreport') + f_avg = make_fname('avg') + f_png = make_fname('png') + + f = sys.stdout + f.write("#!/bin/bash\n") + + if options.oprofile: + f.write("opcontrol --stop\n") + f.write("opcontrol --reset\n") + f.write("opcontrol --start\n") + + f.write("(\n") + + for udelay in (10, 50, 100, 200, 300): + for nspes in range(options.min_spes, options.max_spes+1): + cmd = "./benchmark_nop -n %d -u %d -N %d\n" % (nspes, udelay, njobs[udelay]) + f.write(cmd) + f.write(cmd) + + f.write(") | tee %s\n" % (f_results,)) + + if options.oprofile: + f.write("opcontrol --dump\n") + f.write("opcontrol --stop\n") + f.write("opreport -l | head -100 > %s\n" % (f_opreport,)) + + f.write("./split_and_avg_results.py %s > %s\n" % (f_results, f_avg)) + f.write("./plot_speedup.py %s -o %s\n" % (f_avg, f_png)) + + +if __name__ == '__main__': + main() diff --git a/gcell/src/apps/plot_speedup.py b/gcell/src/apps/plot_speedup.py new file mode 100755 index 000000000..96277f85c --- /dev/null +++ b/gcell/src/apps/plot_speedup.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python + +from optparse import OptionParser +from pylab import * +from pprint import pprint +import os.path + + +def add_entry(d, nspes, speedup, work_incr): + if d.has_key(work_incr): + d[work_incr].append((nspes, speedup)) + else: + d[work_incr] = [(nspes, speedup)] + +def parse_file(f): + d = {} + for line in f: + items = [float(x) for x in line.split()] + # print "items =", items + nspes = items[0] + work_incr = int(1e6 * items[1]) + speedup = items[4] + add_entry(d, nspes, speedup, work_incr) + return d + + +class plot_data(object): + def __init__(self, filenames, output_filename): + self.fig = figure(1, figsize=(8, 6), facecolor='w') + self.sp = self.fig.add_subplot(1,1,1) + self.sp.set_xlabel("nspes", fontweight="bold") + self.sp.set_ylabel("speedup", fontweight="bold") + self.sp.grid(True) + # print 'rcParams["legend.fontsize"] =', rcParams["legend.fontsize"] + rcParams["legend.fontsize"] = 10 + + + self.markers = { + 10 : 'o', + 50 : 's', + 100 : '^', + 200 : 'D', + 300 : 'v', + 400 : '>', + 500 : 'h' + } + + if len(filenames) == 1: + f = filenames[0] + d = parse_file(open(f)) + self.make_single_plot(d, f) + + else: + for f in filenames: + d = parse_file(open(f)) + self.make_plot(d, f, f == filenames[0]) + + if output_filename: + savefig(output_filename) + else: + show() + + + def make_single_plot(self, d, filename): + def style(k): + return self.markers[k] + + tag, ext = os.path.splitext(os.path.basename(filename)) + title(tag) + keys = d.keys() + keys.sort() + keys.reverse() + for k in keys: + vlist = d[k] # list of 2-tuples + xs = [v[0] for v in vlist] + ys = [v[1] for v in vlist] + plot(xs, ys, style(k), label="%d us" % (k,)) + + x = legend(loc=2) + + def make_plot(self, d, filename, first): + def style(k): + if first: + return self.markers[k] + else: + return 'k' + self.markers[k] + + tag, ext = os.path.splitext(os.path.basename(filename)) + keys = d.keys() + keys.sort() + keys.reverse() + for k in keys: + vlist = d[k] # list of 2-tuples + xs = [v[0] for v in vlist] + ys = [v[1] for v in vlist] + plot(xs, ys, style(k), label="%s %d us" % (tag, k)) + + x = legend(loc=2) + +def main(): + usage="%prog: [options] input_filename..." + description = "Plot R*.avg files from benchmark_nop.py" + parser = OptionParser(usage=usage, description=description) + parser.add_option('-o', '--output', default=None, metavar="FILE", + help="generate .png file") + (options, args) = parser.parse_args() + if len(args) < 1: + parser.print_help() + raise SystemExit, 1 + + filenames = args + dc = plot_data(filenames, options.output) + + + +if __name__ == '__main__': + try: + main() + except KeyboardInterrupt: + pass + diff --git a/gcell/src/apps/results-071223 b/gcell/src/apps/results-071223 new file mode 100644 index 000000000..271617121 --- /dev/null +++ b/gcell/src/apps/results-071223 @@ -0,0 +1,126 @@ +nspes: 1 udelay: 1 elapsed_time: 26.117 njobs: 1e+06 us/job: 26.117 +nspes: 1 udelay: 1 elapsed_time: 26.058 njobs: 1e+06 us/job: 26.058 +nspes: 1 udelay: 1 elapsed_time: 26.737 njobs: 1e+06 us/job: 26.737 +nspes: 2 udelay: 1 elapsed_time: 23.585 njobs: 1e+06 us/job: 23.585 +nspes: 2 udelay: 1 elapsed_time: 21.958 njobs: 1e+06 us/job: 21.958 +nspes: 2 udelay: 1 elapsed_time: 21.034 njobs: 1e+06 us/job: 21.034 +nspes: 3 udelay: 1 elapsed_time: 25.819 njobs: 1e+06 us/job: 25.819 +nspes: 3 udelay: 1 elapsed_time: 23.719 njobs: 1e+06 us/job: 23.719 +nspes: 3 udelay: 1 elapsed_time: 21.711 njobs: 1e+06 us/job: 21.711 +nspes: 4 udelay: 1 elapsed_time: 20.210 njobs: 1e+06 us/job: 20.210 +nspes: 4 udelay: 1 elapsed_time: 20.558 njobs: 1e+06 us/job: 20.558 +nspes: 4 udelay: 1 elapsed_time: 20.957 njobs: 1e+06 us/job: 20.957 +nspes: 5 udelay: 1 elapsed_time: 24.571 njobs: 1e+06 us/job: 24.571 +nspes: 5 udelay: 1 elapsed_time: 20.207 njobs: 1e+06 us/job: 20.207 +nspes: 5 udelay: 1 elapsed_time: 21.976 njobs: 1e+06 us/job: 21.976 +nspes: 6 udelay: 1 elapsed_time: 22.601 njobs: 1e+06 us/job: 22.601 +nspes: 6 udelay: 1 elapsed_time: 18.794 njobs: 1e+06 us/job: 18.794 +nspes: 6 udelay: 1 elapsed_time: 19.755 njobs: 1e+06 us/job: 19.755 +nspes: 1 udelay: 5 elapsed_time: 28.047 njobs: 1e+06 us/job: 28.047 +nspes: 1 udelay: 5 elapsed_time: 27.265 njobs: 1e+06 us/job: 27.265 +nspes: 1 udelay: 5 elapsed_time: 27.555 njobs: 1e+06 us/job: 27.555 +nspes: 2 udelay: 5 elapsed_time: 21.130 njobs: 1e+06 us/job: 21.130 +nspes: 2 udelay: 5 elapsed_time: 21.067 njobs: 1e+06 us/job: 21.067 +nspes: 2 udelay: 5 elapsed_time: 21.607 njobs: 1e+06 us/job: 21.607 +nspes: 3 udelay: 5 elapsed_time: 23.712 njobs: 1e+06 us/job: 23.712 +nspes: 3 udelay: 5 elapsed_time: 23.658 njobs: 1e+06 us/job: 23.658 +nspes: 3 udelay: 5 elapsed_time: 25.277 njobs: 1e+06 us/job: 25.277 +nspes: 4 udelay: 5 elapsed_time: 22.264 njobs: 1e+06 us/job: 22.264 +nspes: 4 udelay: 5 elapsed_time: 20.970 njobs: 1e+06 us/job: 20.970 +nspes: 4 udelay: 5 elapsed_time: 21.533 njobs: 1e+06 us/job: 21.533 +nspes: 5 udelay: 5 elapsed_time: 21.504 njobs: 1e+06 us/job: 21.504 +nspes: 5 udelay: 5 elapsed_time: 21.956 njobs: 1e+06 us/job: 21.956 +nspes: 5 udelay: 5 elapsed_time: 21.333 njobs: 1e+06 us/job: 21.333 +nspes: 6 udelay: 5 elapsed_time: 20.639 njobs: 1e+06 us/job: 20.639 +nspes: 6 udelay: 5 elapsed_time: 23.022 njobs: 1e+06 us/job: 23.022 +nspes: 6 udelay: 5 elapsed_time: 22.453 njobs: 1e+06 us/job: 22.453 +nspes: 1 udelay: 10 elapsed_time: 27.780 njobs: 1e+06 us/job: 27.780 +nspes: 1 udelay: 10 elapsed_time: 27.683 njobs: 1e+06 us/job: 27.683 +nspes: 1 udelay: 10 elapsed_time: 26.803 njobs: 1e+06 us/job: 26.803 +nspes: 2 udelay: 10 elapsed_time: 20.878 njobs: 1e+06 us/job: 20.878 +nspes: 2 udelay: 10 elapsed_time: 22.430 njobs: 1e+06 us/job: 22.430 +nspes: 2 udelay: 10 elapsed_time: 20.952 njobs: 1e+06 us/job: 20.952 +nspes: 3 udelay: 10 elapsed_time: 22.752 njobs: 1e+06 us/job: 22.752 +nspes: 3 udelay: 10 elapsed_time: 24.294 njobs: 1e+06 us/job: 24.294 +nspes: 3 udelay: 10 elapsed_time: 23.935 njobs: 1e+06 us/job: 23.935 +nspes: 4 udelay: 10 elapsed_time: 20.437 njobs: 1e+06 us/job: 20.437 +nspes: 4 udelay: 10 elapsed_time: 21.498 njobs: 1e+06 us/job: 21.498 +nspes: 4 udelay: 10 elapsed_time: 20.521 njobs: 1e+06 us/job: 20.521 +nspes: 5 udelay: 10 elapsed_time: 22.704 njobs: 1e+06 us/job: 22.704 +nspes: 5 udelay: 10 elapsed_time: 21.106 njobs: 1e+06 us/job: 21.106 +nspes: 5 udelay: 10 elapsed_time: 22.800 njobs: 1e+06 us/job: 22.800 +nspes: 6 udelay: 10 elapsed_time: 21.098 njobs: 1e+06 us/job: 21.098 +nspes: 6 udelay: 10 elapsed_time: 22.749 njobs: 1e+06 us/job: 22.749 +nspes: 6 udelay: 10 elapsed_time: 19.651 njobs: 1e+06 us/job: 19.651 +nspes: 1 udelay: 50 elapsed_time: 54.621 njobs: 1e+06 us/job: 54.621 +nspes: 1 udelay: 50 elapsed_time: 54.548 njobs: 1e+06 us/job: 54.548 +nspes: 1 udelay: 50 elapsed_time: 54.641 njobs: 1e+06 us/job: 54.641 +nspes: 2 udelay: 50 elapsed_time: 30.837 njobs: 1e+06 us/job: 30.837 +nspes: 2 udelay: 50 elapsed_time: 30.933 njobs: 1e+06 us/job: 30.933 +nspes: 2 udelay: 50 elapsed_time: 30.044 njobs: 1e+06 us/job: 30.044 +nspes: 3 udelay: 50 elapsed_time: 24.170 njobs: 1e+06 us/job: 24.170 +nspes: 3 udelay: 50 elapsed_time: 23.798 njobs: 1e+06 us/job: 23.798 +nspes: 3 udelay: 50 elapsed_time: 23.515 njobs: 1e+06 us/job: 23.515 +nspes: 4 udelay: 50 elapsed_time: 23.011 njobs: 1e+06 us/job: 23.011 +nspes: 4 udelay: 50 elapsed_time: 21.382 njobs: 1e+06 us/job: 21.382 +nspes: 4 udelay: 50 elapsed_time: 20.531 njobs: 1e+06 us/job: 20.531 +nspes: 5 udelay: 50 elapsed_time: 24.157 njobs: 1e+06 us/job: 24.157 +nspes: 5 udelay: 50 elapsed_time: 21.119 njobs: 1e+06 us/job: 21.119 +nspes: 5 udelay: 50 elapsed_time: 22.055 njobs: 1e+06 us/job: 22.055 +nspes: 6 udelay: 50 elapsed_time: 19.136 njobs: 1e+06 us/job: 19.136 +nspes: 6 udelay: 50 elapsed_time: 20.607 njobs: 1e+06 us/job: 20.607 +nspes: 6 udelay: 50 elapsed_time: 20.527 njobs: 1e+06 us/job: 20.527 +nspes: 1 udelay: 100 elapsed_time: 107.531 njobs: 1e+06 us/job: 107.531 +nspes: 1 udelay: 100 elapsed_time: 107.607 njobs: 1e+06 us/job: 107.607 +nspes: 1 udelay: 100 elapsed_time: 107.532 njobs: 1e+06 us/job: 107.532 +nspes: 2 udelay: 100 elapsed_time: 53.950 njobs: 1e+06 us/job: 53.950 +nspes: 2 udelay: 100 elapsed_time: 53.920 njobs: 1e+06 us/job: 53.920 +nspes: 2 udelay: 100 elapsed_time: 54.232 njobs: 1e+06 us/job: 54.232 +nspes: 3 udelay: 100 elapsed_time: 37.987 njobs: 1e+06 us/job: 37.987 +nspes: 3 udelay: 100 elapsed_time: 38.778 njobs: 1e+06 us/job: 38.778 +nspes: 3 udelay: 100 elapsed_time: 39.042 njobs: 1e+06 us/job: 39.042 +nspes: 4 udelay: 100 elapsed_time: 31.192 njobs: 1e+06 us/job: 31.192 +nspes: 4 udelay: 100 elapsed_time: 31.090 njobs: 1e+06 us/job: 31.090 +nspes: 4 udelay: 100 elapsed_time: 31.472 njobs: 1e+06 us/job: 31.472 +nspes: 5 udelay: 100 elapsed_time: 28.490 njobs: 1e+06 us/job: 28.490 +nspes: 5 udelay: 100 elapsed_time: 27.574 njobs: 1e+06 us/job: 27.574 +nspes: 5 udelay: 100 elapsed_time: 27.013 njobs: 1e+06 us/job: 27.013 +nspes: 6 udelay: 100 elapsed_time: 26.635 njobs: 1e+06 us/job: 26.635 +nspes: 6 udelay: 100 elapsed_time: 24.036 njobs: 1e+06 us/job: 24.036 +nspes: 6 udelay: 100 elapsed_time: 26.174 njobs: 1e+06 us/job: 26.174 +nspes: 1 udelay: 300 elapsed_time: 320.618 njobs: 1e+06 us/job: 320.618 +nspes: 1 udelay: 300 elapsed_time: 320.635 njobs: 1e+06 us/job: 320.635 +nspes: 1 udelay: 300 elapsed_time: 320.699 njobs: 1e+06 us/job: 320.699 +nspes: 2 udelay: 300 elapsed_time: 160.314 njobs: 1e+06 us/job: 160.314 +nspes: 2 udelay: 300 elapsed_time: 160.340 njobs: 1e+06 us/job: 160.340 +nspes: 2 udelay: 300 elapsed_time: 160.312 njobs: 1e+06 us/job: 160.312 +nspes: 3 udelay: 300 elapsed_time: 106.878 njobs: 1e+06 us/job: 106.878 +nspes: 3 udelay: 300 elapsed_time: 106.875 njobs: 1e+06 us/job: 106.875 +nspes: 3 udelay: 300 elapsed_time: 106.871 njobs: 1e+06 us/job: 106.871 +nspes: 4 udelay: 300 elapsed_time: 80.158 njobs: 1e+06 us/job: 80.158 +nspes: 4 udelay: 300 elapsed_time: 80.163 njobs: 1e+06 us/job: 80.163 +nspes: 4 udelay: 300 elapsed_time: 80.154 njobs: 1e+06 us/job: 80.154 +nspes: 5 udelay: 300 elapsed_time: 64.156 njobs: 1e+06 us/job: 64.156 +nspes: 5 udelay: 300 elapsed_time: 64.250 njobs: 1e+06 us/job: 64.250 +nspes: 5 udelay: 300 elapsed_time: 64.158 njobs: 1e+06 us/job: 64.158 +nspes: 6 udelay: 300 elapsed_time: 53.633 njobs: 1e+06 us/job: 53.633 +nspes: 6 udelay: 300 elapsed_time: 53.541 njobs: 1e+06 us/job: 53.541 +nspes: 6 udelay: 300 elapsed_time: 53.617 njobs: 1e+06 us/job: 53.617 +nspes: 1 udelay: 500 elapsed_time: 533.638 njobs: 1e+06 us/job: 533.638 +nspes: 1 udelay: 500 elapsed_time: 533.649 njobs: 1e+06 us/job: 533.649 +nspes: 1 udelay: 500 elapsed_time: 533.618 njobs: 1e+06 us/job: 533.618 +nspes: 2 udelay: 500 elapsed_time: 266.810 njobs: 1e+06 us/job: 266.810 +nspes: 2 udelay: 500 elapsed_time: 266.814 njobs: 1e+06 us/job: 266.814 +nspes: 2 udelay: 500 elapsed_time: 266.893 njobs: 1e+06 us/job: 266.893 +nspes: 3 udelay: 500 elapsed_time: 177.875 njobs: 1e+06 us/job: 177.875 +nspes: 3 udelay: 500 elapsed_time: 177.878 njobs: 1e+06 us/job: 177.878 +nspes: 3 udelay: 500 elapsed_time: 177.875 njobs: 1e+06 us/job: 177.875 +nspes: 4 udelay: 500 elapsed_time: 133.417 njobs: 1e+06 us/job: 133.417 +nspes: 4 udelay: 500 elapsed_time: 133.483 njobs: 1e+06 us/job: 133.483 +nspes: 4 udelay: 500 elapsed_time: 133.407 njobs: 1e+06 us/job: 133.407 +nspes: 5 udelay: 500 elapsed_time: 106.723 njobs: 1e+06 us/job: 106.723 +nspes: 5 udelay: 500 elapsed_time: 106.728 njobs: 1e+06 us/job: 106.728 +nspes: 5 udelay: 500 elapsed_time: 106.722 njobs: 1e+06 us/job: 106.722 +nspes: 6 udelay: 500 elapsed_time: 88.943 njobs: 1e+06 us/job: 88.943 +nspes: 6 udelay: 500 elapsed_time: 88.941 njobs: 1e+06 us/job: 88.941 +nspes: 6 udelay: 500 elapsed_time: 88.944 njobs: 1e+06 us/job: 88.944 diff --git a/gcell/src/apps/split_and_avg_results.py b/gcell/src/apps/split_and_avg_results.py new file mode 100755 index 000000000..8a750fac9 --- /dev/null +++ b/gcell/src/apps/split_and_avg_results.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python +# +# Copyright 2007,2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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 3, or (at your option) +# any later version. +# +# GNU Radio 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +""" +input file looks like this: + +nspes: 1 udelay: 10 elapsed_time: 6.842 njobs: 500000 speedup: 0.731 +nspes: 2 udelay: 10 elapsed_time: 4.093 njobs: 500000 speedup: 1.221 +""" + +import sys +from optparse import OptionParser +from pprint import pprint + +class data(object): + def __init__(self, nspes, work_per_job, elapsed_time, njobs): + self.nspes = nspes + self.work_per_job = work_per_job # seconds + self.elapsed_time = elapsed_time # seconds + self.njobs = njobs + self.speedup = work_per_job * njobs / elapsed_time + + def __repr__(self): + return "<data nspes=%d work_per_job=%s elapsed_time=%s njobs=%s speedup=%s>" % ( + self.nspes, (self.work_per_job), + (self.elapsed_time), + (self.njobs), + (self.speedup)) + +def cmp_data(x, y): + t = x.nspes - y.nspes + if t == 0: + t = x.work_per_job - y.work_per_job + if t < 0: + return -1 + elif t > 0: + return +1 + else: + return 0 + return t + +def main(): + usage = "usage: %prog [options] input_filename" + parser = OptionParser(usage=usage) + (options, args) = parser.parse_args() + if len(args) != 1: + parser.print_help() + raise SystemExit, 1 + input_filename = args[0] + + + m = {} + for line in open(input_filename, "r"): + s = line.split() + nspes = int(s[1]) + work_per_job = int(s[3]) * 1e-6 + elapsed_time = float(s[5]) + njobs = float(s[7]) + d = data(nspes, work_per_job, elapsed_time, njobs) + + # collect lists that have the same values for nspes and work_per_job + # so we can generate an average elapsed_time from all observations + key = (nspes, work_per_job) + v = m.get(key, []) + v.append(d) + m[key] = v + + r = [] + for k, v in m.iteritems(): + total_elapsed_time = sum([x.elapsed_time for x in v]) + r.append(data(v[0].nspes, + v[0].work_per_job, + total_elapsed_time/len(v), + v[0].njobs)) + + r.sort(cmp_data) + + #pprint(r) + for t in r: + print t.nspes, t.work_per_job, t.elapsed_time, t.njobs, t.speedup + +if __name__ == '__main__': + main() diff --git a/gcell/src/apps/spu/Makefile.am b/gcell/src/apps/spu/Makefile.am new file mode 100644 index 000000000..c94fe18eb --- /dev/null +++ b/gcell/src/apps/spu/Makefile.am @@ -0,0 +1,32 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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 3, or (at your option) +# any later version. +# +# GNU Radio 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + + +include $(top_srcdir)/Makefile.common.spu + +AM_CPPFLAGS = $(GCELL_SPU_INCLUDES) + +# SPU executables + +noinst_PROGRAMS = \ + benchmark_procs + +benchmark_procs_SOURCES = benchmark_procs.c +benchmark_procs_LDADD = $(GCELL_SPU_LA) diff --git a/gcell/src/apps/spu/benchmark_procs.c b/gcell/src/apps/spu/benchmark_procs.c new file mode 100644 index 000000000..8d5b40653 --- /dev/null +++ b/gcell/src/apps/spu/benchmark_procs.c @@ -0,0 +1,75 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <gc_delay.h> +#include <gc_declare_proc.h> +#include <string.h> + +#define _UNUSED __attribute__((unused)) + + +static void +benchmark_udelay(const gc_job_direct_args_t *input, + gc_job_direct_args_t *output _UNUSED, + const gc_job_ea_args_t *eaa _UNUSED) +{ + gc_udelay(input->arg[0].u32); +} + +GC_DECLARE_PROC(benchmark_udelay, "benchmark_udelay"); + + + +static void +benchmark_put_zeros(const gc_job_direct_args_t *input _UNUSED, + gc_job_direct_args_t *output _UNUSED, + const gc_job_ea_args_t *eaa) +{ + for (unsigned int i = 0; i < eaa->nargs; i++){ + if (eaa->arg[i].direction == GCJD_DMA_PUT) + memset(eaa->arg[i].ls_addr, 0, eaa->arg[i].put_size); + } +} + +GC_DECLARE_PROC(benchmark_put_zeros, "benchmark_put_zeros"); + + +static void +benchmark_copy(const gc_job_direct_args_t *input _UNUSED, + gc_job_direct_args_t *output, + const gc_job_ea_args_t *eaa) +{ + if (eaa->nargs != 2 + || eaa->arg[0].direction != GCJD_DMA_PUT + || eaa->arg[1].direction != GCJD_DMA_GET){ + output->arg[0].s32 = -1; + return; + } + + output->arg[0].s32 = 0; + unsigned n = eaa->arg[0].put_size; + if (eaa->arg[1].get_size < n) + n = eaa->arg[1].get_size; + + memcpy(eaa->arg[0].ls_addr, eaa->arg[1].ls_addr, n); +} + +GC_DECLARE_PROC(benchmark_copy, "benchmark_copy"); diff --git a/gcell/src/apps/test_all.cc b/gcell/src/apps/test_all.cc new file mode 100644 index 000000000..e652de21d --- /dev/null +++ b/gcell/src/apps/test_all.cc @@ -0,0 +1,38 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <cppunit/TextTestRunner.h> + +#include <qa_lib.h> + + +int +main(int argc, char **argv) +{ + + CppUnit::TextTestRunner runner; + + runner.addTest(qa_lib::suite()); + + bool was_successful = runner.run("", false); + + return was_successful ? 0 : 1; +} diff --git a/gcell/src/ibm/Makefile.am b/gcell/src/ibm/Makefile.am new file mode 100644 index 000000000..8013e6a3a --- /dev/null +++ b/gcell/src/ibm/Makefile.am @@ -0,0 +1,98 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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 3, or (at your option) +# any later version. +# +# GNU Radio 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +include $(top_srcdir)/Makefile.common + +EXTRA_DIST = \ + ./README \ + ./sync/ppu_source/atomic_add.h \ + ./sync/ppu_source/atomic_add_return.h \ + ./sync/ppu_source/atomic_dec_and_test.h \ + ./sync/ppu_source/atomic_dec.h \ + ./sync/ppu_source/atomic_dec_if_positive.h \ + ./sync/ppu_source/atomic_dec_return.h \ + ./sync/ppu_source/atomic.h \ + ./sync/ppu_source/atomic_inc.h \ + ./sync/ppu_source/atomic_inc_return.h \ + ./sync/ppu_source/atomic_read.h \ + ./sync/ppu_source/atomic_set.h \ + ./sync/ppu_source/atomic_sub_and_test.h \ + ./sync/ppu_source/atomic_sub.h \ + ./sync/ppu_source/atomic_sub_return.h \ + ./sync/ppu_source/complete_all.h \ + ./sync/ppu_source/complete.h \ + ./sync/ppu_source/completion.h \ + ./sync/ppu_source/cond_broadcast.h \ + ./sync/ppu_source/cond.h \ + ./sync/ppu_source/cond_init.h \ + ./sync/ppu_source/cond_signal.h \ + ./sync/ppu_source/cond_wait.h \ + ./sync/ppu_source/init_completion.h \ + ./sync/ppu_source/libsync.h \ + ./sync/ppu_source/mutex.h \ + ./sync/ppu_source/mutex_init.h \ + ./sync/ppu_source/mutex_lock.h \ + ./sync/ppu_source/mutex_trylock.h \ + ./sync/ppu_source/mutex_unlock.h \ + ./sync/ppu_source/pdt_libsync_config.xml \ + ./sync/ppu_source/pdt_libsync.xml \ + ./sync/ppu_source/sync_utils.h \ + ./sync/ppu_source/trace_libsync.h \ + ./sync/ppu_source/wait_for_completion.h \ + ./sync/spu_source/atomic_add.h \ + ./sync/spu_source/atomic_add_return.h \ + ./sync/spu_source/atomic_dec_and_test.h \ + ./sync/spu_source/atomic_dec.h \ + ./sync/spu_source/atomic_dec_if_positive.h \ + ./sync/spu_source/atomic_dec_return.h \ + ./sync/spu_source/atomic.h \ + ./sync/spu_source/atomic_inc.h \ + ./sync/spu_source/atomic_inc_return.h \ + ./sync/spu_source/atomic_read.h \ + ./sync/spu_source/atomic_set.h \ + ./sync/spu_source/atomic_sub_and_test.h \ + ./sync/spu_source/atomic_sub.h \ + ./sync/spu_source/atomic_sub_return.h \ + ./sync/spu_source/complete_all.h \ + ./sync/spu_source/complete.h \ + ./sync/spu_source/completion.h \ + ./sync/spu_source/cond_broadcast.h \ + ./sync/spu_source/cond.h \ + ./sync/spu_source/cond_init.h \ + ./sync/spu_source/cond_signal.h \ + ./sync/spu_source/cond_wait.h \ + ./sync/spu_source/init_completion.h \ + ./sync/spu_source/libsync.h \ + ./sync/spu_source/mutex.h \ + ./sync/spu_source/mutex_init.h \ + ./sync/spu_source/mutex_lock.h \ + ./sync/spu_source/mutex_trylock.h \ + ./sync/spu_source/mutex_unlock.h \ + ./sync/spu_source/read_lock.h \ + ./sync/spu_source/read_trylock.h \ + ./sync/spu_source/read_unlock.h \ + ./sync/spu_source/rwlock_init.h \ + ./sync/spu_source/sync_irq.h \ + ./sync/spu_source/sync_utils.h \ + ./sync/spu_source/trace_libsync.h \ + ./sync/spu_source/wait_for_completion.h \ + ./sync/spu_source/write_lock.h \ + ./sync/spu_source/write_trylock.h \ + ./sync/spu_source/write_unlock.h diff --git a/gcell/src/ibm/README b/gcell/src/ibm/README new file mode 100644 index 000000000..9420fcc46 --- /dev/null +++ b/gcell/src/ibm/README @@ -0,0 +1,10 @@ +This directory and below contains code from IBM licensed under the +"Modified BSD license." It was extracted unmodified from the IBM Cell +SDK 3.0 library source tarball, lib_source.tar, typically found in +/opt/cell/sdk/src/lib_source.tar. + +We've done this because this code doesn't come unpacked in the native +(cell) installation of the SDK 3.0, and thus we can't just add a +-I/path/to/this/stuff in our Makefiles. If this changes, we'll delete +this code from here, and fix our Makefiles. In the meanwhile, this +reduces the probability of build problems. diff --git a/gcell/src/ibm/sync/ppu_source/atomic.h b/gcell/src/ibm/sync/ppu_source/atomic.h new file mode 100644 index 000000000..105f7bf37 --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/atomic.h @@ -0,0 +1,112 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +/* + * atomic.h - PPE atomic SHM counter operations. + * + * Interfaces patterned after, and hopefully compatible + * with PowerPC64-Linux atomic counter operations. Uses + * 32b values for various counters. + */ +#ifndef _PPU_ATOMIC_H_ +#define _PPU_ATOMIC_H_ + +#include <ppu_intrinsics.h> +#include "sync_utils.h" + +typedef unsigned int atomic_t __attribute__ ((aligned (128))); + + +/* atomic_ea_t is a 64bit effective address that points to + * an atomic_t variable + */ +typedef unsigned long long atomic_ea_t; + +/** + * ASSUMPTIONS: + * On the PPE, the size of a reservation granule is 128 bytes + * (a cache-line), so when a programmer puts a reservation on an + * address, that whole cacheline is reserved. Therefore both + * the PPE and SPE can participate in an atomic operation as long as + * lwarx and getllar operate on the same cacheline. + */ + + +/* + * atomically loads and replaces the value v with val. + * Returns the old value at v + */ +static __inline int _atomic_replace(atomic_ea_t v, int val) +{ + int old; + void *p; + + SYNC_ULL_TO_PTR(v, p); + + do { + old = (int)__lwarx(p); + } while (__stwcx(p, (unsigned int)val) == 0); + + return old; +} + + +/* + * atomically loads the value at v, adds val, replaces the + * value at v with the sum. Returns the old value at v + */ +static __inline int _atomic_modify(atomic_ea_t v, int val) +{ + int oldval, newval; + void *p; + + SYNC_ULL_TO_PTR(v, p); + + do { + oldval = (int)__lwarx(p); + newval = oldval + val; + } while (__stwcx(p, (unsigned int)newval) == 0); + + return oldval; +} + + +#endif /* _PPU_ATOMIC_H_ */ + diff --git a/gcell/src/ibm/sync/ppu_source/atomic_add.h b/gcell/src/ibm/sync/ppu_source/atomic_add.h new file mode 100644 index 000000000..dd7a5b25a --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/atomic_add.h @@ -0,0 +1,62 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_ATOMIC_ADD_H_ +#define _PPU_ATOMIC_ADD_H_ + +#include "sync_utils.h" +#include "atomic.h" + +/** + * atomic_add - atomically add to a counter. + * @v: handle to effective address of counter. + * @a: value to be added. + * + * Atomically add a value to a counter in system memory. + * The only restriction is that @v must be word aligned. + */ +static __inline void _atomic_add(int a, atomic_ea_t v) +{ + _atomic_modify (v, a); +} + + + +#endif /* _PPU_ATOMIC_ADD_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/atomic_add_return.h b/gcell/src/ibm/sync/ppu_source/atomic_add_return.h new file mode 100644 index 000000000..0fe127565 --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/atomic_add_return.h @@ -0,0 +1,66 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_ATOMIC_ADD_RETURN_H_ +#define _PPU_ATOMIC_ADD_RETURN_H_ + +#include "sync_utils.h" +#include "atomic.h" + +/** + * atomic_add_return - atomically add to a counter and return previous value. + * @v: handle to effective address of counter. + * @a: value to be added. + * + * Atomically add a value to a counter in system memory. + * The only restriction is that @v must be word aligned. + * + * This routine implements the "fetch and add" primitive + * that is described in "Book I PowerPC User Instruction + * Set Architecture" + * Returns the previous value from system memory. + */ +static __inline int _atomic_add_return(int a, atomic_ea_t v) +{ + return _atomic_modify (v, a); +} + + +#endif /* _PPU_ATOMIC_ADD_RETURN_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/atomic_dec.h b/gcell/src/ibm/sync/ppu_source/atomic_dec.h new file mode 100644 index 000000000..4f82f04e0 --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/atomic_dec.h @@ -0,0 +1,60 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_ATOMIC_DEC_H_ +#define _PPU_ATOMIC_DEC_H_ + +#include "sync_utils.h" +#include "atomic.h" + +/** + * atomic_dec - atomically decrement a counter. + * @v: handle to effective address of location to be modified. + * + * Atomically decrement a counter in system memory. The only + * restriction is that @v must be word aligned. + */ +static __inline void _atomic_dec(atomic_ea_t v) +{ + _atomic_modify (v, -1); +} + + +#endif /* _PPU_ATOMIC_DEC_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/atomic_dec_and_test.h b/gcell/src/ibm/sync/ppu_source/atomic_dec_and_test.h new file mode 100644 index 000000000..5093d4059 --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/atomic_dec_and_test.h @@ -0,0 +1,63 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_ATOMIC_DEC_AND_TEST_H_ +#define _PPU_ATOMIC_DEC_AND_TEST_H_ + +#include "sync_utils.h" +#include "atomic.h" + +/** + * atomic_dec_and_test - atomically decrement and test if previous==0. + * @v: handle to effective address of counter. + * + * Atomically decrement a counter in system memory and test + * if previous==0. The only restriction is that @v must be + * word aligned. + * + * Returns the previous value from system memory. + */ +static __inline int _atomic_dec_and_test(atomic_ea_t v) +{ + return (_atomic_modify(v, -1) == 0) ? 1 : 0; +} + + +#endif /* _PPU_ATOMIC_DEC_AND_TEST_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/atomic_dec_if_positive.h b/gcell/src/ibm/sync/ppu_source/atomic_dec_if_positive.h new file mode 100644 index 000000000..c4d113bfd --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/atomic_dec_if_positive.h @@ -0,0 +1,76 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_ATOMIC_DEC_IF_POSITIVE_H_ +#define _PPU_ATOMIC_DEC_IF_POSITIVE_H_ + +#include <ppu_intrinsics.h> +#include "sync_utils.h" +#include "atomic.h" + +/* + * atomic_dec_if_positive - atomically decrement if counter is positive. + * + * v: handle to effective address of counter. + * + * Atomically decrement a counter if its value is positive. + * The only restriction is that v must be word aligned. + * + * + * Returns the old value of the counter, minus 1. + */ +static __inline int _atomic_dec_if_positive(atomic_ea_t v) +{ + int ret; + int tmp; + void *p; + + SYNC_ULL_TO_PTR(v, p); + + do { + tmp = (int)__lwarx(p); + ret = tmp - 1; + tmp = (tmp > 0) ? ret : tmp; + } while (__stwcx(p, (unsigned)tmp) == 0); + + return ret; +} + +#endif /* _PPU_ATOMIC_DEC_IF_POSITIVE_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/atomic_dec_return.h b/gcell/src/ibm/sync/ppu_source/atomic_dec_return.h new file mode 100644 index 000000000..cd87893fa --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/atomic_dec_return.h @@ -0,0 +1,68 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_ATOMIC_DEC_RETURN_H_ +#define _PPU_ATOMIC_DEC_RETURN_H_ + +#include "sync_utils.h" +#include "atomic.h" + +/** + * atomic_dec_return - atomically decrement a counter and return previous value. + * @v: handle to effective address of counter. + * + * Atomically decrement a counter in system memory and return its + * previous value. The only restriction is that @v must be word + * aligned. + * + * This routine implements the "fetch and decrement" + * primitive that is described in "Book I PowerPC User + * Instruction Set Architecture". + * + * Returns the previous value from system memory. + */ +static __inline int _atomic_dec_return(atomic_ea_t v) +{ + return _atomic_modify (v, -1); +} + + + +#endif /* _PPU_ATOMIC_DEC_RETURN_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/atomic_inc.h b/gcell/src/ibm/sync/ppu_source/atomic_inc.h new file mode 100644 index 000000000..714aecbc0 --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/atomic_inc.h @@ -0,0 +1,59 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_ATOMIC_INC_H_ +#define _PPU_ATOMIC_INC_H_ + +#include "sync_utils.h" +#include "atomic.h" + +/** + * atomic_inc - atomically increment a counter in system memory. + * @v: handle to effective address of counter. + * + * Atomically increment a counter in system memory. + * The only restriction is that @v must be word aligned. + */ +static __inline void _atomic_inc(atomic_ea_t v) +{ + _atomic_modify (v, 1); +} + +#endif /* _PPU_ATOMIC_INC_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/atomic_inc_return.h b/gcell/src/ibm/sync/ppu_source/atomic_inc_return.h new file mode 100644 index 000000000..95178f50d --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/atomic_inc_return.h @@ -0,0 +1,66 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_ATOMIC_INC_RETURN_H_ +#define _PPU_ATOMIC_INC_RETURN_H_ + +#include <sync_utils.h> +#include <atomic.h> + + +/** + * atomic_inc_return - atomically increment a counter and return previous. + * @v: handle to effective address of counter. + * + * Atomically increment a counter in system memory. + * The only restriction is that @v must be word aligned. + * + * This routine implements the "fetch and increment" + * primitive that is described in "Book I PowerPC User + * Instruction Set Architecture" + * + * Returns the previous value from system memory. + */ +static __inline int _atomic_inc_return(atomic_ea_t v) +{ + return _atomic_modify (v, 1); +} + +#endif /* _PPU_ATOMIC_INC_RETURN_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/atomic_read.h b/gcell/src/ibm/sync/ppu_source/atomic_read.h new file mode 100644 index 000000000..258fd516c --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/atomic_read.h @@ -0,0 +1,62 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_ATOMIC_READ_H_ +#define _PPU_ATOMIC_READ_H_ + +#include "sync_utils.h" +#include "atomic.h" + +/* + * On PowerPC architecture, if v is a word_aligned address, then + * a load of that address is guaranteed to be atomic. An atomic + * read operation is simply a load. + */ +static __inline int _atomic_read(atomic_ea_t v) +{ + volatile int *p; + + SYNC_ULL_TO_PTR(v, p); + + return (*p); +} + + +#endif /* _PPU_ATOMIC_READ_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/atomic_set.h b/gcell/src/ibm/sync/ppu_source/atomic_set.h new file mode 100644 index 000000000..e624af40d --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/atomic_set.h @@ -0,0 +1,66 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_ATOMIC_SET_H_ +#define _PPU_ATOMIC_SET_H_ + +#include "sync_utils.h" +#include "atomic.h" + +/** + * atomic_set - atomically set a counter in system memory. + * @v: this is a 64bit address that points to an atomic_t + * + * Atomically set a counter to a given value. The only + * restriction is that @v must be word aligned. + * + * This routine implements the "fetch and store" + * primitive that is described in "Book I PowerPC User + * Instruction Set Architecture" + * + * Returns the previous value from system memory. + */ +static __inline void _atomic_set(atomic_ea_t v, int val) +{ + _atomic_replace (v, val); +} + + +#endif /* _PPU_ATOMIC_SET_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/atomic_sub.h b/gcell/src/ibm/sync/ppu_source/atomic_sub.h new file mode 100644 index 000000000..b8d35975a --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/atomic_sub.h @@ -0,0 +1,61 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_ATOMIC_SUB_H_ +#define _PPU_ATOMIC_SUB_H_ + +#include "sync_utils.h" +#include "atomic.h" + +/** + * atomic_sub - atomically subtract from a counter. + * @v: handle to effective address of counter. + * @a: value to be subtracted. + * + * Atomically subtract a value from a counter in system memory. + * The only restriction is that @v must be word aligned. + */ +static __inline void _atomic_sub(int a, atomic_ea_t v) +{ + _atomic_modify (v, -a); +} + + +#endif /* _PPU_ATOMIC_SUB_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/atomic_sub_and_test.h b/gcell/src/ibm/sync/ppu_source/atomic_sub_and_test.h new file mode 100644 index 000000000..37ba58896 --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/atomic_sub_and_test.h @@ -0,0 +1,63 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_ATOMIC_SUB_AND_TEST_H_ +#define _PPU_ATOMIC_SUB_AND_TEST_H_ + +#include "sync_utils.h" +#include "atomic.h" + +/** + * atomic_sub_and_test - atomically subtract and test if previous==0. + * @v: handle to effective address of counter. + * @a: value to be subtracted. + * + * Atomically subtract a value from a counter in system memory + * and test if previous==0. The only restriction is that @v + * must be word aligned. + * + * Returns the previous value from system memory. + */ +static __inline int _atomic_sub_and_test(int a, atomic_ea_t v) +{ + return (_atomic_modify(v, -a) == 0) ? 1 : 0; +} + +#endif /* _PPU_ATOMIC_SUB_AND_TEST_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/atomic_sub_return.h b/gcell/src/ibm/sync/ppu_source/atomic_sub_return.h new file mode 100644 index 000000000..084bfa6b1 --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/atomic_sub_return.h @@ -0,0 +1,65 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_ATOMIC_SUB_RETURN_H_ +#define _PPU_ATOMIC_SUB_RETURN_H_ + +#include <sync_utils.h> +#include <atomic.h> + + +/** + * atomic_sub_return - atomically subtract from a counter & return previous. + * @v: handle to effective address of counter. + * @a: value to be subtracted. + * + * Atomically subtract a value from a counter in system memory. + * The only restriction is that @v must be word aligned. + * + * Returns the previous value from system memory. + */ + + +static __inline int _atomic_sub_return(int a, atomic_ea_t v) +{ + return _atomic_modify (v, -a); +} + +#endif /* _PPU_ATOMIC_SUB_RETURN_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/complete.h b/gcell/src/ibm/sync/ppu_source/complete.h new file mode 100644 index 000000000..8633463f7 --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/complete.h @@ -0,0 +1,61 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_COMPLETE_H_ +#define _PPU_COMPLETE_H_ + +#include <ppu_intrinsics.h> +#include "sync_utils.h" +#include "completion.h" + + +static __inline void _complete (completion_ea_t comp) +{ + unsigned int old; + void *p; + + SYNC_ULL_TO_PTR(comp, p); + + do { + old = __lwarx(p); + } while (__stwcx(p, (unsigned int)1) == 0); +} + +#endif /* _PPU_COMPLETE_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/complete_all.h b/gcell/src/ibm/sync/ppu_source/complete_all.h new file mode 100644 index 000000000..c12eb7f03 --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/complete_all.h @@ -0,0 +1,70 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_COMPLETE_ALL_H_ +#define _PPU_COMPLETE_ALL_H_ + +#include <ppu_intrinsics.h> +#include "sync_utils.h" +#include "completion.h" + +/** + * complete_all - indicate that a completion is true. + * @completion: handle to effective address of completion variable. + * + * Indicate that all are completed is true by storing + * MAX_THREADS_WAITING to the completionition variable. + */ + +static __inline void _complete_all(completion_ea_t comp) +{ + unsigned int old; + unsigned int val = MAX_THREADS_WAITING; + + void *p; + + SYNC_ULL_TO_PTR(comp, p); + + do { + old = __lwarx(p); + } while (__stwcx(p, val) == 0); +} + +#endif /* _PPU_COMPLETE_ALL_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/completion.h b/gcell/src/ibm/sync/ppu_source/completion.h new file mode 100644 index 000000000..b74bdaae7 --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/completion.h @@ -0,0 +1,50 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ + +#ifndef _PPU_COMPLETION_H_ +#define _PPU_COMPLETION_H_ + + +#define MAX_THREADS_WAITING 32000 + +typedef unsigned long long completion_ea_t; + +#endif /* _PPU_COMPLETION_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/cond.h b/gcell/src/ibm/sync/ppu_source/cond.h new file mode 100644 index 000000000..9a38f71a4 --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/cond.h @@ -0,0 +1,65 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_COND_VAR_H_ +#define _PPU_COND_VAR_H_ + +#include <mutex.h> +#include <sync_utils.h> + + +typedef struct +{ + short num_threads_signal; /* the number of threads that are going to be waken up. + There are 3 values possible for this parameter, 0, 1, + or num_threads_waiting*/ + short num_threads_waiting; /* the number of threads that are waiting to be awaken */ +} condition_variable_t __attribute__ ((aligned (16))); + +typedef unsigned long long cond_ea_t; /* a system memory 64 bit address that points to + * a valid condition_variable_t */ + +typedef union { + unsigned long long ull; + unsigned int ui[2]; +} val64; + + +#endif /* _PPU_COND_VAR_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/cond_broadcast.h b/gcell/src/ibm/sync/ppu_source/cond_broadcast.h new file mode 100644 index 000000000..b93bf7b37 --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/cond_broadcast.h @@ -0,0 +1,70 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_COND_BROADCAST_H_ +#define _PPU_COND_BROADCAST_H_ + +#include <ppu_intrinsics.h> +#include "sync_utils.h" +#include "cond.h" + +/** + * cond_broadcast - indicate that a condition is true. + * @cond: handle to effective address of condition variable. + */ +static __inline void _cond_broadcast (cond_ea_t cond) +{ + unsigned int val; + void *p; + + SYNC_ULL_TO_PTR(cond, p); + + do { + val = __lwarx(p); + + /* Copy the waiting count (low halfword) to + * the signaled count (high halfword) + */ + val = (val & 0xFFFF) | ((val+1) << 16); + + } while (__stwcx(p, val) == 0); +} + +#endif /* _PPU_COND_BROADCAST_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/cond_init.h b/gcell/src/ibm/sync/ppu_source/cond_init.h new file mode 100644 index 000000000..0dfbd6349 --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/cond_init.h @@ -0,0 +1,66 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_COND_INIT_H_ +#define _PPU_COND_INIT_H_ + +#include "sync_utils.h" +#include "cond.h" + +/** + * cond_init - initialize condition variable. + * @cond: handle to effective address of condition variable. + * + * Only one thread initializes a condition variable. Usually, the + * PPE thread initializes a condidtion variable + * + * Description: Initialize a cond variable to false. + */ +static __inline void _cond_init (cond_ea_t cond) +{ + volatile unsigned int *p; + + SYNC_ULL_TO_PTR(cond, p); + + *p = 0; +} + + +#endif /* _PPU_COND_INIT_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/cond_signal.h b/gcell/src/ibm/sync/ppu_source/cond_signal.h new file mode 100644 index 000000000..dd4874827 --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/cond_signal.h @@ -0,0 +1,74 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_COND_SIGNAL_H_ +#define _PPU_COND_SIGNAL_H_ + +#include <ppu_intrinsics.h> +#include "sync_utils.h" +#include "cond.h" + +/* + * _cond_signal: signaling any of the waiting threads to wake up. + */ +static __inline void _cond_signal (cond_ea_t cond) +{ + unsigned int val, waiting, signaled; + void *p; + + SYNC_ULL_TO_PTR(cond, p); + + do { + val = __lwarx(p); + + waiting = val & 0xFFFF; + signaled = val >> 16; + + /* If no other party is waiting. Don't send a signal. + * Otherwise, increment the signaled halfword. + */ + if (waiting == signaled) break; + val = ((val+1) << 16) | waiting; + + } while (__stwcx(p, val) == 0); +} + + +#endif /* _PPU_COND_SIGNAL_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/cond_wait.h b/gcell/src/ibm/sync/ppu_source/cond_wait.h new file mode 100644 index 000000000..ed5fbecb1 --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/cond_wait.h @@ -0,0 +1,96 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_COND_WAIT_H_ +#define _PPU_COND_WAIT_H_ + +#include <ppu_intrinsics.h> +#include "sync_utils.h" +#include "mutex_lock.h" +#include "mutex_unlock.h" +#include "cond.h" + +static __inline void _cond_wait (cond_ea_t cond, mutex_ea_t mutex) +{ + int delta, cur_delta; + unsigned int val, cond_val, signaled_cnt; + void *p; + + + SYNC_ULL_TO_PTR(cond, p); + + /* Atomically signal we have entered the condition wait by incrementing + * the waiting count. + */ + do { + val = __lwarx(p); + val = (val & ~0xFFFF) | ((val+1) & 0xFFFF); + } while (__stwcx(p, val) == 0); + + + /* Release the lock + */ + _mutex_unlock (mutex); + + /* Determine the signal count needed for this + * participant to be signaled. + */ + + signaled_cnt = val >> 16; + delta = (int)(val & 0xFFFF) - (int)signaled_cnt; + if (delta < 0) delta = -delta; + + /* Wait until the signaled count reaches the count + * previously determined. + */ + do { + cond_val = __lwarx(p); + + cur_delta = (int)(cond_val >> 16) - signaled_cnt; + if (cur_delta < 0) cur_delta = -cur_delta; + + } while (cur_delta < delta); + + /* Relock the mutex + */ + _mutex_lock (mutex); +} + +#endif /* _PPU_COND_WAIT_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/init_completion.h b/gcell/src/ibm/sync/ppu_source/init_completion.h new file mode 100644 index 000000000..8e7081111 --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/init_completion.h @@ -0,0 +1,63 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_INIT_COMPLETION_H_ +#define _PPU_INIT_COMPLETION_H_ + +#include "sync_utils.h" +#include "completion.h" + +/** + * completion_init - initialize completion variable. + * @completion: handle to effective address of completion variable. + * + * Description: Initialize a completion variable to 0. + */ +static __inline void _init_completion(completion_ea_t comp) +{ + volatile unsigned int *p; + + SYNC_ULL_TO_PTR(comp, p); + + *p = 0; +} + + +#endif /* _PPU_INIT_COMPLETION_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/libsync.h b/gcell/src/ibm/sync/ppu_source/libsync.h new file mode 100644 index 000000000..bd2e04347 --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/libsync.h @@ -0,0 +1,114 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_LIBSYNC_H_ +#define _PPU_LIBSYNC_H_ + +#include "sync_utils.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned long long atomic_ea_t; + +extern void atomic_set(atomic_ea_t v, int val); +extern void atomic_add(int a, atomic_ea_t v); +extern void atomic_sub(int a, atomic_ea_t v); +extern void atomic_inc(atomic_ea_t v); +extern void atomic_dec(atomic_ea_t v); + +extern int atomic_read(atomic_ea_t v); +extern int atomic_add_return(int a, atomic_ea_t v); +extern int atomic_sub_return(int a, atomic_ea_t v); +extern int atomic_inc_return(atomic_ea_t v); +extern int atomic_dec_return(atomic_ea_t v); +extern int atomic_sub_and_test(int a, atomic_ea_t v); +extern int atomic_dec_and_test(atomic_ea_t v); +extern int atomic_dec_if_positive(atomic_ea_t v); + +typedef unsigned long long mutex_ea_t; +void mutex_init(mutex_ea_t lock); + +void mutex_lock(mutex_ea_t lock); +int mutex_trylock(mutex_ea_t ea); +void mutex_unlock(mutex_ea_t lock); + +typedef struct +{ + int num_threads_signal; /* the number of threads that are going to be waken up. + There are 3 values possible for this parameter, 0, 1, + or num_threads_waiting*/ + int num_threads_waiting; /* the number of threads that are waiting to be awaken */ +} condition_variable_t __attribute__ ((aligned (16))); + +typedef unsigned long long cond_ea_t; /* a system memory 64 bit address that points to + * a valid condition_variable_t */ + +typedef union { + unsigned long long ull; + unsigned int ui[2]; +} val64; + + +void cond_init (cond_ea_t cond); +void cond_signal (cond_ea_t cond); +void cond_broadcast (cond_ea_t cond); +void cond_wait (cond_ea_t cond, mutex_ea_t mutex); + + +#define MAX_THREADS_WAITING 32000 + +typedef unsigned long long completion_ea_t; + +extern void init_completion(completion_ea_t comp); +extern void wait_for_completion(completion_ea_t comp); +/* +extern void wait_for_completion_irq(completion_ea_t comp); +extern void wait_for_completion_irqsave(completion_ea_t comp); +*/ +extern void complete_all(completion_ea_t comp); +extern void complete (completion_ea_t comp); + +#ifdef __cplusplus +} +#endif + +#endif /* _PPU_LIBSYNC_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/mutex.h b/gcell/src/ibm/sync/ppu_source/mutex.h new file mode 100644 index 000000000..364bb2249 --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/mutex.h @@ -0,0 +1,46 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_MUTEX_H_ +#define _PPU_MUTEX_H_ 1 + +typedef unsigned long long mutex_ea_t; + +#endif /* _PPU_MUTEX_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/mutex_init.h b/gcell/src/ibm/sync/ppu_source/mutex_init.h new file mode 100644 index 000000000..105dc2c57 --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/mutex_init.h @@ -0,0 +1,67 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_MUTEX_INIT_H_ +#define _PPU_MUTEX_INIT_H_ + +#include "sync_utils.h" +#include "mutex.h" +#include "trace_libsync.h" + +/***************************************************************************/ +/** + * mutex_init - initialize the mutex by setting the value + * to 0. + * @lock: handle to effective address of lock variable. + * + * Description: Initialize a mutex. + */ +static __inline void _mutex_init(mutex_ea_t lock) +{ + volatile unsigned int *p; + + SYNC_ULL_TO_PTR(lock, p); + + *p = 0; + + TRACE_MUTEX_INIT(lock); +} + +#endif /* _PPU_MUTEX_INIT_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/mutex_lock.h b/gcell/src/ibm/sync/ppu_source/mutex_lock.h new file mode 100644 index 000000000..75240a141 --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/mutex_lock.h @@ -0,0 +1,78 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_MUTEX_LOCK_H_ +#define _PPU_MUTEX_LOCK_H_ + +#include <ppu_intrinsics.h> +#include "sync_utils.h" +#include "mutex.h" +#include "trace_libsync.h" + +/* function: _mutex_lock + * + * Aquire a lock at a location in system memory by waiting for the + * value to become zero, then atomically storing 1. + */ +static __inline void _mutex_lock (mutex_ea_t lock) +{ + unsigned int done = 0; + void *p; +#ifdef LIBSYNC_TRACE + unsigned int miss = 0; +#endif /* LIBSYNC_TRACE */ + + TRACE_MUTEX_LOCK_ENTRY(interval); + + SYNC_ULL_TO_PTR(lock, p); + + do { + if (__lwarx(p) == 0) done = __stwcx(p, (unsigned int) 1); +#ifdef LIBSYNC_TRACE + /* if we missed the lock, note it.. */ + if (done == 0) miss = 1; +#endif + } while (done == 0); + __isync(); + + TRACE_MUTEX_LOCK_EXIT(interval, lock, miss); +} + +#endif /* _PPU_MUTEX_LOCK_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/mutex_trylock.h b/gcell/src/ibm/sync/ppu_source/mutex_trylock.h new file mode 100644 index 000000000..445196c74 --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/mutex_trylock.h @@ -0,0 +1,81 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_MUTEX_TRYLOCK_H_ +#define _PPU_MUTEX_TRYLOCK_H_ + +#include <ppu_intrinsics.h> +#include "sync_utils.h" +#include "mutex.h" +#include "trace_libsync.h" + +/** + * mutex_trylock - acquire a lock, or return immediately. + * @lock: handle to effective address of lock variable. + * + * Description: Acquire a lock, or return immediately + * without polling for availability. + * + * Context: The application should not call this interface + * from a tight loop!! Use spin_lock() instead. + * + * Attempt to immediately aquire a lock at a location in system memory, + * and return 1 if the lock was aquired or 0 otherwise. + */ +static __inline int _mutex_trylock (mutex_ea_t lock) +{ + int val; + int ret = 0; + void *p; + + SYNC_ULL_TO_PTR(lock, p); + + do { + val = (int)__lwarx(p); + if (val) break; + } while ((ret = __stwcx(p, (unsigned int)1)) == 0); + __isync(); + + TRACE_MUTEX_TRYLOCK(lock,ret); + + return (ret); +} + +#endif /* _PPU_MUTEX_TRYLOCK_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/mutex_unlock.h b/gcell/src/ibm/sync/ppu_source/mutex_unlock.h new file mode 100644 index 000000000..e5255be02 --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/mutex_unlock.h @@ -0,0 +1,64 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_MUTEX_UNLOCK_H_ +#define _PPU_MUTEX_UNLOCK_H_ + +#include "mutex.h" +#include "atomic.h" +#include "trace_libsync.h" + +/* function: _mutex_unlock + * + * Release a lock held at address 'lock' in system memory. + * For the PU, this routine is the same _unlock, and is + * provided here as a simple convenience for programmers + * (to match the interfaces that are supported on the SPU). + * All I need to do is a store since store is an atomic operation by itself + */ +static __inline void _mutex_unlock (mutex_ea_t lock) +{ + _atomic_replace ((atomic_ea_t)lock, 0); + + TRACE_MUTEX_UNLOCK(lock); +} + + +#endif /* _PPU_MUTEX_UNLOCK_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/pdt_libsync.xml b/gcell/src/ibm/sync/ppu_source/pdt_libsync.xml new file mode 100644 index 000000000..d9ea2ce9f --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/pdt_libsync.xml @@ -0,0 +1,184 @@ +<pdtGroup name="LIBSYNC" id="0x03" version="3.0"> + <!-- PPE events --> + <subGroup name="PPE_MUTEX" id="0xFE03"> + <recordType name="PPE_MUTEX_INIT" description="PPE: mutex lock init" id="0x0003" type="event"> + <include href="/usr/share/pdt/config/pdt_ppe_event_header.xml"/> + <physicalField name="lock" description="Lock address" type="long" toString="0x%x" visible="true"/> + <physicalField name="empty3" description="empty slot 3" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty4" description="empty slot 4" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty5" description="empty slot 5" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty6" description="empty slot 6" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty7" description="empty slot 7" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty8" description="empty slot 8" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty9" description="empty slot 9" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty10" description="empty slot 10" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty11" description="empty slot 11" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty12" description="empty slot 12" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty13" description="empty slot 13" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty14" description="empty slot 14" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty15" description="empty slot 15" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty16" description="empty slot 16" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty17" description="empty slot 17" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty18" description="empty slot 18" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty19" description="empty slot 19" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty20" description="empty slot 20" type="int" toString="0x%x" visible="false"/> + </recordType> + <recordType name="PPE_MUTEX_LOCK" description="PPE: acquire a mutex lock" id="0x0103" type="interval"> + <include href="/usr/share/pdt/config/pdt_ppe_event_header.xml"/> + <physicalField name="lock" description="Lock address" type="long" toString="0x%x" visible="true"/> + <physicalField name="miss" description="Missed" type="int" toString="0x%x" visible="true"/> + <physicalField name="empty4" description="empty slot 4" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty5" description="empty slot 5" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty6" description="empty slot 6" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty7" description="empty slot 7" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty8" description="empty slot 8" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty9" description="empty slot 9" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty10" description="empty slot 10" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty11" description="empty slot 11" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty12" description="empty slot 12" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty13" description="empty slot 13" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty14" description="empty slot 14" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty15" description="empty slot 15" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty16" description="empty slot 16" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty17" description="empty slot 17" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty18" description="empty slot 18" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty19" description="empty slot 19" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty20" description="empty slot 20" type="int" toString="0x%x" visible="false"/> + </recordType> + <recordType name="PPE_MUTEX_TRYLOCK" description="PPE: try to acquire a lock" id="0x0203" type="event"> + <include href="/usr/share/pdt/config/pdt_ppe_event_header.xml"/> + <physicalField name="lock" description="Lock address" type="long" toString="0x%x" visible="true"/> + <physicalField name="ret" description="Try lock return code" type="int" toString="0x%x" visible="true"/> + <physicalField name="empty4" description="empty slot 4" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty5" description="empty slot 5" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty6" description="empty slot 6" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty7" description="empty slot 7" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty8" description="empty slot 8" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty9" description="empty slot 9" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty10" description="empty slot 10" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty11" description="empty slot 11" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty12" description="empty slot 12" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty13" description="empty slot 13" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty14" description="empty slot 14" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty15" description="empty slot 15" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty16" description="empty slot 16" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty17" description="empty slot 17" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty18" description="empty slot 18" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty19" description="empty slot 19" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty20" description="empty slot 20" type="int" toString="0x%x" visible="false"/> + </recordType> + <recordType name="PPE_MUTEX_UNLOCK" description="PPE: unlock a mutex lock" id="0x0303" type="event"> + <include href="/usr/share/pdt/config/pdt_ppe_event_header.xml"/> + <physicalField name="lock" description="Lock address" type="long" toString="0x%x" visible="true"/> + <physicalField name="empty3" description="empty slot 3" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty4" description="empty slot 4" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty5" description="empty slot 5" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty6" description="empty slot 6" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty7" description="empty slot 7" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty8" description="empty slot 8" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty9" description="empty slot 9" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty10" description="empty slot 10" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty11" description="empty slot 11" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty12" description="empty slot 12" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty13" description="empty slot 13" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty14" description="empty slot 14" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty15" description="empty slot 15" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty16" description="empty slot 16" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty17" description="empty slot 17" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty18" description="empty slot 18" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty19" description="empty slot 19" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty20" description="empty slot 20" type="int" toString="0x%x" visible="false"/> + </recordType> + </subGroup> + <!-- SPE events --> + <subGroup name="SPE_MUTEX" id="0xFD03"> + <recordType name="SPE_MUTEX_INIT" description="SPE: mutex lock init" id="0x0403" type="event"> + <include href="/usr/share/pdt/config/pdt_spe_event_header.xml"/> + <physicalField name="lock" description="Lock address" type="long" toString="0x%x" visible="true"/> + <physicalField name="empty3" description="empty slot 3" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty4" description="empty slot 4" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty5" description="empty slot 5" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty6" description="empty slot 6" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty7" description="empty slot 7" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty8" description="empty slot 8" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty9" description="empty slot 9" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty10" description="empty slot 10" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty11" description="empty slot 11" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty12" description="empty slot 12" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty13" description="empty slot 13" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty14" description="empty slot 14" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty15" description="empty slot 15" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty16" description="empty slot 16" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty17" description="empty slot 17" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty18" description="empty slot 18" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty19" description="empty slot 19" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty20" description="empty slot 20" type="int" toString="0x%x" visible="false"/> + </recordType> + <recordType name="SPE_MUTEX_LOCK" description="SPE: acquire a mutex lock" id="0x0503" type="interval"> + <include href="/usr/share/pdt/config/pdt_spe_event_header.xml"/> + <physicalField name="lock" description="Lock address" type="long" toString="0x%x" visible="true"/> + <physicalField name="miss" description="Missed" type="int" toString="0x%x" visible="true"/> + <physicalField name="empty4" description="empty slot 4" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty5" description="empty slot 5" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty6" description="empty slot 6" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty7" description="empty slot 7" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty8" description="empty slot 8" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty9" description="empty slot 9" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty10" description="empty slot 10" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty11" description="empty slot 11" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty12" description="empty slot 12" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty13" description="empty slot 13" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty14" description="empty slot 14" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty15" description="empty slot 15" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty16" description="empty slot 16" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty17" description="empty slot 17" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty18" description="empty slot 18" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty19" description="empty slot 19" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty20" description="empty slot 20" type="int" toString="0x%x" visible="false"/> + </recordType> + <recordType name="SPE_MUTEX_TRYLOCK" description="SPE: try to acquire a mutex lock" id="0x0603" type="event"> + <include href="/usr/share/pdt/config/pdt_spe_event_header.xml"/> + <physicalField name="lock" description="Lock address" type="long" toString="0x%x" visible="true"/> + <physicalField name="ret_val" description="Try lock return code" type="int" toString="0x%x" visible="true"/> + <physicalField name="empty4" description="empty slot 4" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty5" description="empty slot 5" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty6" description="empty slot 6" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty7" description="empty slot 7" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty8" description="empty slot 8" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty9" description="empty slot 9" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty10" description="empty slot 10" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty11" description="empty slot 11" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty12" description="empty slot 12" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty13" description="empty slot 13" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty14" description="empty slot 14" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty15" description="empty slot 15" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty16" description="empty slot 16" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty17" description="empty slot 17" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty18" description="empty slot 18" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty19" description="empty slot 19" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty20" description="empty slot 20" type="int" toString="0x%x" visible="false"/> + </recordType> + <recordType name="SPE_MUTEX_UNLOCK" description="SPE: unlock a mutex lock" id="0x0703" type="event"> + <include href="/usr/share/pdt/config/pdt_spe_event_header.xml"/> + <physicalField name="lock" description="Lock address" type="long" toString="0x%x" visible="true"/> + <physicalField name="empty3" description="empty slot 3" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty4" description="empty slot 4" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty5" description="empty slot 5" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty6" description="empty slot 6" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty7" description="empty slot 7" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty8" description="empty slot 8" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty9" description="empty slot 9" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty10" description="empty slot 10" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty11" description="empty slot 11" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty12" description="empty slot 12" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty13" description="empty slot 13" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty14" description="empty slot 14" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty15" description="empty slot 15" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty16" description="empty slot 16" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty17" description="empty slot 17" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty18" description="empty slot 18" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty19" description="empty slot 19" type="int" toString="0x%x" visible="false"/> + <physicalField name="empty20" description="empty slot 20" type="int" toString="0x%x" visible="false"/> + </recordType> + </subGroup> +</pdtGroup> diff --git a/gcell/src/ibm/sync/ppu_source/pdt_libsync_config.xml b/gcell/src/ibm/sync/ppu_source/pdt_libsync_config.xml new file mode 100644 index 000000000..a0b848d84 --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/pdt_libsync_config.xml @@ -0,0 +1,61 @@ +<pdt_configuration application_name="libsync" output_dir="." version="3.0"> + <groups> + <group name="GENERAL" description="General event types" id="0x00"> + <view yStart="0.0" yEnd="0.2" color="0x0000FF"/> + <include href="/usr/share/pdt/config/pdt_general.xml"/> + </group> + <group name="LIBSPE2" description="CBE libspe 2.0 event types" id="0x01"> + <view yStart="0.2" yEnd="0.4" color="0x00FFFF"/> + <include href="/usr/share/pdt/config/pdt_libspe2.xml"/> + </group> + <group name="MFCIO" description="SPE MFCIO event types" id="0x02"> + <view yStart="0.4" yEnd="0.6" color="0x00FF80"/> + <include href="/usr/share/pdt/config/pdt_mfcio.xml"/> + </group> + <group name="LIBSYNC" description="General event types" id="0x03"> + <view yStart="0.6" yEnd="0.8" color="0xFFFF00"/> + <include href="/usr/share/pdt/config/pdt_libsync.xml"/> + </group> + </groups> +<configuration name="CBE"> +<host name="none"/> +<groupsControl> + <group name="GENERAL" active="true"> + <profile active="false"/> + <!-- The GENERAL group of events are always active--> + </group> + <group name="LIBSPE2" active="true"> + </group> + <group name="LIBSYNC" active="true"> + <sub_group name="PPE_MUTEX" active="true"> + <event name="PPE_MUTEX_INIT" active="true"/> + <event name="PPE_MUTEX_LOCK" active="true"/> + <event name="PPE_MUTEX_TRYLOCK" active="true"/> + <event name="PPE_MUTEX_UNLOCK" active="true"/> + </sub_group> + </group> +</groupsControl> +</configuration> +<!-- --> +<!-- SPEs configuration - this section is read with the CBE configuration --> +<!-- --> +<configuration name="SPE"> +<host name="CBE"/> +<groupsControl> + <group name="GENERAL" active="true"> + <profile active="false"/> + <!-- The GENERAL group of events are always active--> + </group> + <group name="MFCIO" active="true"> + </group> + <group name="LIBSYNC" active="true"> + <sub_group name="SPE_MUTEX" active="true"> + <event name="SPE_MUTEX_INIT" active="true"/> + <event name="SPE_MUTEX_LOCK" active="true"/> + <event name="SPE_MUTEX_TRYLOCK" active="true"/> + <event name="SPE_MUTEX_UNLOCK" active="true"/> + </sub_group> + </group> +</groupsControl> +</configuration> +</pdt_configuration> diff --git a/gcell/src/ibm/sync/ppu_source/sync_utils.h b/gcell/src/ibm/sync/ppu_source/sync_utils.h new file mode 100644 index 000000000..c7120a3cc --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/sync_utils.h @@ -0,0 +1,73 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _PPU_SYNC_UTILS_H_ +#define _PPU_SYNC_UTILS_H_ 1 + +/* SYNC_ULL_TO_PTR - convert a 64-bit unsigned long long to a void + * pointer. + */ +#ifdef __powerpc64__ + +#define SYNC_ULL_TO_PTR(_ull, _ptr) { \ + union { \ + void *ptr; \ + unsigned long long ull; \ + } _x; \ + \ + _x.ull = _ull; \ + _ptr = _x.ptr; \ +} + +#else + +#define SYNC_ULL_TO_PTR(_ull, _ptr) { \ + union { \ + void *ptr[2]; \ + unsigned long long ull; \ + } _x; \ + \ + _x.ull = _ull; \ + _ptr = _x.ptr[1]; \ +} + +#endif + +#endif /* _PPU_SYNC_UTILS_H_ */ diff --git a/gcell/src/ibm/sync/ppu_source/trace_libsync.h b/gcell/src/ibm/sync/ppu_source/trace_libsync.h new file mode 100644 index 000000000..6d6f036e5 --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/trace_libsync.h @@ -0,0 +1,117 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2007 */ +/* International Business Machines Corporation */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef __LIBSYNC_PPU_TRACEHOOKS_H__ +#define __LIBSYNC_PPU_TRACEHOOKS_H__ + +#ifdef LIBSYNC_TRACE + +#include <trace_events.h> + +/* + * last parameter in the trace_even and trace_interval_entry call is + * the stack level to report the PC in the trace record. so 0 means + * the PC of the current frame, 1 means the PC of the caller, etc. + * there's a dilemma here - these macros are included in the inline + * _mutex calls which get called from the (created during build) + * mutex functions in the mutex .c files. in that case, the level + * should be 1 - we don't want the PC of where in the mutex function + * the trace call is happening, we want the PC of whomever is calling + * the mutex function. + * + * but.. an app can call the inline functions - it can #include the + * appropriate libsync mutex .h files, and call the inlined _mutex + * function in their code. in that case, the appropriate level for the + * trace calls would be 0 - the user would want to know where in their + * code the call to the _mutex function is. + * + * so, we'll assume _LEVEL of 0 which is what the inline funtions need. + * when we build the files for libsync, we'll do a -D_LEVEL=1 + */ +#ifndef _LEVEL +#define _LEVEL 0 +#endif + + +#define TRACE_EVENT_MUTEX_INIT 0x0003 + +#define TRACE_MUTEX_INIT(lock) { \ + trace_payload_t payload; \ + payload.dword[0]=(uint64_t)lock; \ + trace_event(TRACE_EVENT_MUTEX_INIT, 1, &payload, "Event=%d, lock=0x%x",_LEVEL); \ +} + +#define TRACE_EVENT_MUTEX_LOCK 0x0103 + +#define TRACE_MUTEX_LOCK_ENTRY(_INTERVAL) \ +trace_interval_p _INTERVAL = trace_interval_entry(TRACE_EVENT_MUTEX_LOCK, _LEVEL) + +#define TRACE_MUTEX_LOCK_EXIT(_INTERVAL,lock,miss) { \ + trace_payload_t payload; \ + payload.dword[0]=(uint64_t)lock; \ + payload.word[2]=(uint32_t)miss; \ + trace_interval_exit(_INTERVAL, 2, &payload, "Event=%d, lock=0x%x, miss=0x%x"); \ +} + +#define TRACE_EVENT_MUTEX_TRYLOCK 0x0203 + +#define TRACE_MUTEX_TRYLOCK(lock,ret) { \ + trace_payload_t payload; \ + payload.dword[0]=(uint64_t)lock; \ + payload.word[2]=(uint32_t)ret; \ + trace_event(TRACE_EVENT_MUTEX_TRYLOCK, 2, &payload, "Event=%d, lock=0x%x, ret=0x%x", _LEVEL); \ +} + +#define TRACE_EVENT_MUTEX_UNLOCK 0x0303 + +#define TRACE_MUTEX_UNLOCK(lock) { \ + trace_payload_t payload; \ + payload.dword[0]=(uint64_t)lock; \ + trace_event(TRACE_EVENT_MUTEX_UNLOCK, 1, &payload, "Event=%d, lock=0x%x", _LEVEL); \ +} + +#else /* LIBSYNC_TRACE */ + +#define TRACE_MUTEX_INIT(lock) +#define TRACE_MUTEX_LOCK_ENTRY(_INTERVAL) +#define TRACE_MUTEX_LOCK_EXIT(_INTERVAL,lock,miss) +#define TRACE_MUTEX_TRYLOCK(lock,ret_val) +#define TRACE_MUTEX_UNLOCK(lock) + +#endif /* LIBSYNC_TRACE */ + +#endif /* __LIBSYNC_PPU_TRACEHOOKS_H__ */ diff --git a/gcell/src/ibm/sync/ppu_source/wait_for_completion.h b/gcell/src/ibm/sync/ppu_source/wait_for_completion.h new file mode 100644 index 000000000..f2b04275a --- /dev/null +++ b/gcell/src/ibm/sync/ppu_source/wait_for_completion.h @@ -0,0 +1,75 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ + +#ifndef _PPU_WAIT_FOR_COMPLETION_H_ +#define _PPU_WAIT_FOR_COMPLETION_H_ + +#include <ppu_intrinsics.h> +#include "sync_utils.h" +#include "completion.h" + + +/** + * completion_wait - wait until a completion is broadcast. + * @comp: handle to effective address of completion variable. + * + * Description: Wait until another processor or device signals + * that a completionition is 'true'. The only restriction here is + * that @comp must be a word aligned address. + * + * Beware: This function hot polls waiting for completion. + */ +static __inline void _wait_for_completion(completion_ea_t comp) +{ + int val; + void *p; + + SYNC_ULL_TO_PTR(comp, p); + + do { + val = (int)__lwarx(p); + if (val != 1) val = (int)__stwcx(p, (unsigned int)0); + } while (val == 0); + __isync(); +} + + +#endif /* _PPU_WAIT_FOR_COMPLETION_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/atomic.h b/gcell/src/ibm/sync/spu_source/atomic.h new file mode 100644 index 000000000..951c26e3f --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/atomic.h @@ -0,0 +1,101 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +/* + * atomic.h - SPU atomic SHM counter operations. + * + * Interfaces patterned after, and hopefully compatible + * with PowerPC64-Linux atomic counter operations. Uses + * 32b values for various counters. + */ +#ifndef _SPU_ATOMIC_H_ +#define _SPU_ATOMIC_H_ + +#include <sync_utils.h> +#include <spu_mfcio.h> + + +/* atomic_eaddr_t is a 64bit effective address + * that points to an atomic_t variable */ +typedef unsigned long long atomic_ea_t; + +#define DECL_ATOMIC_VARS() \ + char _tmp[256]; \ + char *tmp = (char *) ALIGN(_tmp, 128); \ + volatile s32 *buf = (volatile s32 *) &tmp[0]; \ + u32 size = 128, tagid = 0; \ + s32 ret_val; \ + u32 offset; \ + addr64 ea64 + +/* __atomic_op +* Internal routine to acquire lock line reservation +* then conditionally modify the counter variable +* pointed to by 'v'. The 'replace' flag indicates +* whether or not this is to be an arithmetic R-M-W +* or a simple replace operation. +*/ +#define ATOMIC_OP(__v, __val, __replace, __final_val) \ +{ \ + char __tmp[256]; \ + char *_tmp = (char *) ALIGN(__tmp, 128); \ + volatile s32 *_buf = (volatile s32 *) &_tmp[0]; \ + u32 _size = 128, _tagid = 0; \ + s32 _status, _ret_val; \ + u32 _offset; \ + addr64 _ea64; \ + \ + _ea64.ull = ALIGN128_EA(__v); \ + _offset = OFFSET128_EA_U32(__v); \ + do { \ + MFC_DMA(_buf, _ea64, _size, _tagid, MFC_GETLLAR_CMD); \ + spu_readch (MFC_RdAtomicStat); \ + \ + _ret_val = _buf[_offset]; \ + _buf[_offset] = (__replace) ? __val : _ret_val + __val; \ + MFC_DMA(_buf, _ea64, _size, _tagid, MFC_PUTLLC_CMD); \ + _status = spu_readch(MFC_RdAtomicStat); \ + } while (_status != 0); \ + \ + __final_val = _ret_val; \ +} + +#endif /* _SPU_ATOMIC_H_ */ + diff --git a/gcell/src/ibm/sync/spu_source/atomic_add.h b/gcell/src/ibm/sync/spu_source/atomic_add.h new file mode 100644 index 000000000..7606ae05b --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/atomic_add.h @@ -0,0 +1,62 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_ATOMIC_ADD_H_ +#define _SPU_ATOMIC_ADD_H_ + +#include <sync_utils.h> +#include <atomic.h> + +/** + * atomic_add - atomically add to a counter. + * @v: handle to effective address of counter. + * @a: value to be added. + * + * Atomically add a value to a counter in system memory. + * The only restriction is that @v must be word aligned. + */ +static __inline void _atomic_add(int a, atomic_ea_t v) +{ + int ret_val; + ATOMIC_OP (v, a, 0, ret_val); +} + + +#endif /* _SPU_ATOMIC_ADD_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/atomic_add_return.h b/gcell/src/ibm/sync/spu_source/atomic_add_return.h new file mode 100644 index 000000000..35f07adf6 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/atomic_add_return.h @@ -0,0 +1,69 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_ATOMIC_ADD_RETURN_H_ +#define _SPU_ATOMIC_ADD_RETURN_H_ + +#include <sync_utils.h> +#include <atomic.h> +/** + * atomic_add_return - atomically add to a counter and return previous value. + * @v: handle to effective address of counter. + * @a: value to be added. + * + * Atomically add a value to a counter in system memory. + * The only restriction is that @v must be word aligned. + * + * This routine implements the "fetch and add" primitive + * that is described in "Book I PowerPC User Instruction + * Set Architecture", but uses MFC lock line reservation + * operations instead of lwarx/stwcx. + * + * Returns the previous value from system memory. + */ +static __inline int _atomic_add_return(int a, atomic_ea_t v) +{ + int ret_val; + ATOMIC_OP(v, a, 0, ret_val); + return ret_val; +} + + +#endif /* _SPU_ATOMIC_ADD_RETURN_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/atomic_dec.h b/gcell/src/ibm/sync/spu_source/atomic_dec.h new file mode 100644 index 000000000..30ca7c514 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/atomic_dec.h @@ -0,0 +1,61 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_ATOMIC_DEC_H_ +#define _SPU_ATOMIC_DEC_H_ + +#include <sync_utils.h> +#include <atomic.h> + +/** + * atomic_dec - atomically decrement a counter. + * @v: handle to effective address of location to be modified. + * + * Atomically decrement a counter in system memory. The only + * restriction is that @v must be word aligned. + */ +static __inline void _atomic_dec(atomic_ea_t v) +{ + int ret_val; + ATOMIC_OP (v, -1, 0, ret_val); +} + + +#endif /* _SPU_ATOMIC_DEC_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/atomic_dec_and_test.h b/gcell/src/ibm/sync/spu_source/atomic_dec_and_test.h new file mode 100644 index 000000000..b3c829820 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/atomic_dec_and_test.h @@ -0,0 +1,64 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_ATOMIC_DEC_AND_TEST_H_ +#define _SPU_ATOMIC_DEC_AND_TEST_H_ + +#include <sync_utils.h> +#include <atomic.h> + +/** + * atomic_dec_and_test - atomically decrement and test if previous==0. + * @v: handle to effective address of counter. + * + * Atomically decrement a counter in system memory and test + * if previous==0. The only restriction is that @v must be + * word aligned. + * + * Returns the previous value from system memory. + */ +static __inline int _atomic_dec_and_test(atomic_ea_t v) +{ + int ret_val; + ATOMIC_OP(v, -1, 0, ret_val); + return (ret_val == 0) ? 1 : 0; +} + +#endif /* _SPU_ATOMIC_DEC_AND_TEST_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/atomic_dec_if_positive.h b/gcell/src/ibm/sync/spu_source/atomic_dec_if_positive.h new file mode 100644 index 000000000..2a01ec307 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/atomic_dec_if_positive.h @@ -0,0 +1,86 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_ATOMIC_DEC_IF_POSITIVE_H_ +#define _SPU_ATOMIC_DEC_IF_POSITIVE_H_ + +#include <sync_utils.h> +#include <atomic.h> + +/** + * atomic_dec_if_positive - atomically decrement if counter is positive. + * @v: handle to effective address of counter. + * + * Atomically decrement a counter if its value is positive. + * The only restriction is that @v must be word aligned. + * +* + * Returns the old value of the counter, minus 1. + */ +static __inline int _atomic_dec_if_positive(atomic_ea_t v) +{ + DECL_ATOMIC_VARS(); + s32 status; + + ea64.ull = ALIGN128_EA(v); + offset = OFFSET128_EA_U32(v); + do { + MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD); + spu_readch(MFC_RdAtomicStat); + + ret_val = buf[offset] - 1; + if (likely(ret_val >= 0)) { + buf[offset] = ret_val; + MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLC_CMD); + status = spu_readch(MFC_RdAtomicStat); + } else { + MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLC_CMD); + spu_readch(MFC_RdAtomicStat); + status = 0; + break; + } + } while (status != 0); + + return ret_val; +} + + + +#endif /* _SPU_ATOMIC_DEC_IF_POSITIVE_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/atomic_dec_return.h b/gcell/src/ibm/sync/spu_source/atomic_dec_return.h new file mode 100644 index 000000000..45effb689 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/atomic_dec_return.h @@ -0,0 +1,70 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_ATOMIC_DEC_RETURN_H_ +#define _SPU_ATOMIC_DEC_RETURN_H_ + +#include <sync_utils.h> +#include <atomic.h> + +/** + * atomic_dec_return - atomically decrement a counter and return previous value. + * @v: handle to effective address of counter. + * + * Atomically decrement a counter in system memory and return its + * previous value. The only restriction is that @v must be word + * aligned. + * + * This routine implements the "fetch and decrement" + * primitive that is described in "Book I PowerPC User + * Instruction Set Architecture", but uses MFC lock line + * reservation operations instead of lwarx/stwcx. + * + * Returns the previous value from system memory. + */ +static __inline int _atomic_dec_return(atomic_ea_t v) +{ + int ret_val; + ATOMIC_OP(v, -1, 0, ret_val); + return ret_val; +} + + +#endif /* _SPU_ATOMIC_DEC_RETURN_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/atomic_inc.h b/gcell/src/ibm/sync/spu_source/atomic_inc.h new file mode 100644 index 000000000..6800efea3 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/atomic_inc.h @@ -0,0 +1,61 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_ATOMIC_INC_H_ +#define _SPU_ATOMIC_INC_H_ + +#include <sync_utils.h> +#include <atomic.h> + +/** + * atomic_inc - atomically increment a counter in system memory. + * @v: handle to effective address of counter. + * + * Atomically increment a counter in system memory. + * The only restriction is that @v must be word aligned. + */ +static __inline void _atomic_inc(atomic_ea_t v) +{ + int ret_val; + ATOMIC_OP (v, 1, 0, ret_val); +} + + +#endif /* _SPU_ATOMIC_INC_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/atomic_inc_return.h b/gcell/src/ibm/sync/spu_source/atomic_inc_return.h new file mode 100644 index 000000000..89361a0a1 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/atomic_inc_return.h @@ -0,0 +1,70 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_ATOMIC_INC_RETURN_H_ +#define _SPU_ATOMIC_INC_RETURN_H_ + +#include <sync_utils.h> +#include <atomic.h> + + +/** + * atomic_inc_return - atomically increment a counter and return previous. + * @v: handle to effective address of counter. + * + * Atomically increment a counter in system memory. + * The only restriction is that @v must be word aligned. + * + * This routine implements the "fetch and increment" + * primitive that is described in "Book I PowerPC User + * Instruction Set Architecture", but uses MFC lock line + * reservation operations instead of lwarx/stwcx. + * + * Returns the previous value from system memory. + */ +static __inline int _atomic_inc_return(atomic_ea_t v) +{ + int ret_val; + ATOMIC_OP(v, 1, 0, ret_val); + return ret_val; +} + + +#endif /* _SPU_ATOMIC_INC_RETURN_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/atomic_read.h b/gcell/src/ibm/sync/spu_source/atomic_read.h new file mode 100644 index 000000000..711a0ad26 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/atomic_read.h @@ -0,0 +1,78 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_ATOMIC_READ_H_ +#define _SPU_ATOMIC_READ_H_ + +#include <sync_utils.h> +#include <atomic.h> + +/** + * atomic_read - read an atomic counter. + * @v: handle to effective address of counter. + * + * Read the current value of an atomic counter. + */ +static __inline int _atomic_read(atomic_ea_t v) +{ + DECL_ATOMIC_VARS(); + + /* reserve a tag for use */ + tagid = mfc_tag_reserve(); + + u32 oldtmask, tagmask = 1 << (tagid & 31); + + ea64.ull = ALIGN128_EA(v); + offset = OFFSET128_EA_U32(v); + + MFC_DMA(buf, ea64, size, tagid & 31, MFC_GET_CMD); + oldtmask = spu_readch(MFC_RdTagMask); + spu_writech(MFC_WrTagMask, tagmask); + spu_writech(MFC_WrTagUpdate, MFC_TAG_UPDATE_ANY); + spu_readch(MFC_RdTagStat); + spu_writech(MFC_WrTagMask, oldtmask); + + mfc_tag_release (tagid); + ret_val = buf[offset]; + return ret_val; +} + + +#endif /* _SPU_ATOMIC_READ_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/atomic_set.h b/gcell/src/ibm/sync/spu_source/atomic_set.h new file mode 100644 index 000000000..261d28a3d --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/atomic_set.h @@ -0,0 +1,68 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_ATOMIC_SET_H_ +#define _SPU_ATOMIC_SET_H_ + +#include <sync_utils.h> +#include <atomic.h> + +/** + * atomic_set - atomically set a counter in system memory. + * @v: handle to effective address of counter. + * + * Atomically set a counter to a given value. The only + * restriction is that @v must be word aligned. + * + * This routine implements the "fetch and store" + * primitive that is described in "Book I PowerPC User + * Instruction Set Architecture", but uses MFC lock line + * reservation operations instead of lwarx/stwcx. + * + * Returns the previous value from system memory. + */ +static __inline void _atomic_set(atomic_ea_t v, int val) +{ + int ret_val; + ATOMIC_OP(v, val, 1, ret_val); +} + + +#endif /* _SPU_ATOMIC_SET_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/atomic_sub.h b/gcell/src/ibm/sync/spu_source/atomic_sub.h new file mode 100644 index 000000000..f366e1dee --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/atomic_sub.h @@ -0,0 +1,64 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_ATOMIC_SUB_H_ +#define _SPU_ATOMIC_SUB_H_ + +#include <sync_utils.h> +#include <atomic.h> + +/** + * atomic_sub - atomically subtract from a counter. + * @v: handle to effective address of counter. + * @a: value to be subtracted. + * + * Atomically subtract a value from a counter in system memory. + * The only restriction is that @v must be word aligned. + */ +static __inline void _atomic_sub(int a, atomic_ea_t v) +{ + int ret_val; + + ATOMIC_OP (v, -a, 0, ret_val); +} + + + +#endif /* _SPU_ATOMIC_SUB_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/atomic_sub_and_test.h b/gcell/src/ibm/sync/spu_source/atomic_sub_and_test.h new file mode 100644 index 000000000..fe5824a43 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/atomic_sub_and_test.h @@ -0,0 +1,66 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_ATOMIC_SUB_AND_TEST_H_ +#define _SPU_ATOMIC_SUB_AND_TEST_H_ + +#include <sync_utils.h> +#include <atomic.h> + +/** + * atomic_sub_and_test - atomically subtract and test if previous==0. + * @v: handle to effective address of counter. + * @a: value to be subtracted. + * + * Atomically subtract a value from a counter in system memory + * and test if previous==0. The only restriction is that @v + * must be word aligned. + * + * Returns the previous value from system memory. + */ +static __inline int _atomic_sub_and_test(int a, atomic_ea_t v) +{ + int ret_val; + ATOMIC_OP(v, -a, 0, ret_val); + return (ret_val == 0) ? 1 : 0; +} + + +#endif /* _SPU_ATOMIC_SUB_AND_TEST_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/atomic_sub_return.h b/gcell/src/ibm/sync/spu_source/atomic_sub_return.h new file mode 100644 index 000000000..5dbed5b85 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/atomic_sub_return.h @@ -0,0 +1,69 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_ATOMIC_SUB_RETURN_H_ +#define _SPU_ATOMIC_SUB_RETURN_H_ + +#include <sync_utils.h> +#include <atomic.h> + + +/** + * atomic_sub_return - atomically subtract from a counter & return previous. + * @v: handle to effective address of counter. + * @a: value to be subtracted. + * + * Atomically subtract a value from a counter in system memory. + * The only restriction is that @v must be word aligned. + * + * Returns the previous value from system memory. + */ +static __inline int _atomic_sub_return(int a, atomic_ea_t v) +{ + int ret_val; + ATOMIC_OP(v, -a, 0, ret_val); + return ret_val; + //return __atomic_op(v, -a, 0); +} + + + + +#endif /* _SPU_ATOMIC_SUB_RETURN_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/complete.h b/gcell/src/ibm/sync/spu_source/complete.h new file mode 100644 index 000000000..6a7808650 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/complete.h @@ -0,0 +1,67 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_COMPLETE_H_ +#define _SPU_COMPLETE_H_ + +#include "sync_utils.h" +#include <spu_mfcio.h> +#include "completion.h" + +static __inline void _complete(completion_ea_t completion) +{ + DECL_COMPLETION_VARS(); + + ea64.ull = ALIGN128_EA(completion); + offset = OFFSET128_EA_U32(completion); + MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD); + spu_readch(MFC_RdAtomicStat); + + /* set the completionition variable to exactly one so + * only one thread can be awaken */ + buf[offset] = 1; + MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLUC_CMD); + spu_readch(MFC_RdAtomicStat); +} + + + + +#endif /* _SPU_COMPLETE_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/complete_all.h b/gcell/src/ibm/sync/spu_source/complete_all.h new file mode 100644 index 000000000..5f9c3dcfa --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/complete_all.h @@ -0,0 +1,74 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_COMPLETE_ALL_H_ +#define _SPU_COMPLETE_ALL_H_ + +#include "sync_utils.h" +#include <spu_mfcio.h> +#include "completion.h" + +/** + * completion_broadcast - indicate that a completion is true. + * @completion: handle to effective address of completion variable. + * + * Indicate that a completionition is true by storing '1' to the + * completionition variable. + */ +static __inline void _complete_all(completion_ea_t completion) +{ + DECL_COMPLETION_VARS(); + + ea64.ull = ALIGN128_EA(completion); + offset = OFFSET128_EA_U32(completion); + MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD); + spu_readch(MFC_RdAtomicStat); + + /* set the completionition variable to the count. So that + * all the threads */ + buf[offset] = MAX_THREADS_WAITING; + MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLUC_CMD); + spu_readch(MFC_RdAtomicStat); +} + + + + +#endif /* _SPU_COMPLETE_ALL_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/completion.h b/gcell/src/ibm/sync/spu_source/completion.h new file mode 100644 index 000000000..4a302d25c --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/completion.h @@ -0,0 +1,68 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +/* + * cond.h - simple condition wait & broadcast operations. + * + * Interrupt aware versions of the routines are supported. + * Applications should call either '_irq' or '_irqsave' + * forms of the functions when interrupts are enabled. + */ + +#ifndef __SPU_COMPLETION_H__ +#define __SPU_COMPLETION_H__ + +#include "sync_utils.h" + +#define MAX_THREADS_WAITING 32000 +typedef unsigned long long completion_ea_t; + + +#define DECL_COMPLETION_VARS() \ + char _tmp[256]; \ + char *tmp = (char *) ALIGN(_tmp, 128); \ + volatile s32 *buf = (volatile s32 *) &tmp[0]; \ + u32 size = 128, tagid = 0; \ + u32 offset; \ + addr64 ea64 + + + +#endif /* __SPU_COMPLETION_H__ */ diff --git a/gcell/src/ibm/sync/spu_source/cond.h b/gcell/src/ibm/sync/spu_source/cond.h new file mode 100644 index 000000000..ceb3285d9 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/cond.h @@ -0,0 +1,69 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_COND_VAR_H_ +#define _SPU_COND_VAR_H_ + +#include "sync_utils.h" +typedef struct +{ + int num_threads_signal; /* the number of threads that are going to be waken up. + There are 3 values possible for this parameter, 0, 1, + or num_threads_waiting*/ + int num_threads_waiting; /* the number of threads that are waiting to be awaken */ +} condition_variable_t __attribute__ ((aligned (128))); + +typedef eaddr_t cond_ea_t; /* a system memory 64 bit address that points to + * a valid condition_variable_t */ + + + + +#define DECL_COND_VARS() \ + char _tmp[256]; \ + char *tmp = (char *) ALIGN(_tmp, 128); \ + volatile s32 *buf = (volatile s32 *) &tmp[0]; \ + u32 size = 128, tagid = 0; \ + s32 status, ret_val; \ + u32 offset; \ + addr64 ea64; \ + condition_variable_t cond_var + +#endif /* _SPU_COND_VAR_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/cond_broadcast.h b/gcell/src/ibm/sync/spu_source/cond_broadcast.h new file mode 100644 index 000000000..15a1da330 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/cond_broadcast.h @@ -0,0 +1,73 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_COND_BROADCAST_H_ +#define _SPU_COND_BROADCAST_H_ + +#include "sync_utils.h" +#include "cond.h" +#include <spu_mfcio.h> + +/** + * cond_broadcast - indicate that a condition is true. + * @cond: handle to effective address of condition variable. + */ +static __inline void _cond_broadcast(cond_ea_t cond) +{ + char _tmp[256]; + char *tmp = (char *) ALIGN(_tmp, 128); + volatile unsigned short *buf = (volatile unsigned short *) &tmp[0]; + unsigned int size = 128, tagid = 0; + u32 offset; + addr64 ea64; + + ea64.ull = ALIGN128_EA(cond); + offset = OFFSET128_EA_U16(cond); + MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD); + spu_readch(MFC_RdAtomicStat); + + /* set the condition variable to the count. So that + * all the threads */ + buf[offset] = buf[offset + 1]; + MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLUC_CMD); + spu_readch(MFC_RdAtomicStat); +} + +#endif /* _SPU_COND_BROADCAST_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/cond_init.h b/gcell/src/ibm/sync/spu_source/cond_init.h new file mode 100644 index 000000000..7202e5352 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/cond_init.h @@ -0,0 +1,127 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_COND_INIT_H_ +#define _SPU_COND_INIT_H_ + +#include "sync_utils.h" +#include "cond.h" +#include <spu_mfcio.h> + + +/** + * cond_init - initialize condition variable. + * @cond: handle to effective address of condition variable. + * + * + * Conditional Variable - is a synchronization device that allows + * SPE and PPE threads to suspend execution and relinquish the + * processors until some predicate on shared data is satisfied. + * The basic operations on conditions are: signal the condition + * (when the predicate becomes true), and wait for the condition, + * suspending the thread execution until anoter thread signals the + * condition + * + * A condition variable must always be associated with a mutex, to + * avoid the race condition where a thread prepares to wait on a + * condition variable and another thread signals the condition just + * before the first thread actually waits on it. + * + * cond_init initializes the condition variable cond. + * + * cond_signal restarts one of the threads that are waiting on the + * condition variable cond. If no threads are waiting on cond, nothing + * happens. If several threads are waiting on cond, exactly one + * is restarted, but it is not specified which + * + * cond_broadcast restarts all the threads that are waiting on the + * condition variable cond. Nothing happens if no threads are waiting + * on cond + * + * cond_wait atomically unlocks the mutex and waits for the condition + * variable cond to be signaled. The mutex must be lock locked by + * the calling thread on the entrance to cond_wait. Before returning + * to the calling thread, cond_wait re-acquires mutex. + * + * Only one thread initializes a condition variable. Usually, the + * PPE thread initializes a condidtion variable, however, a cond_init + * function is provided here for completeness + * + * Description: Initialize a cond variable to false. + */ +static __inline void _cond_init(cond_ea_t cond ) +{ + char _tmp[256]; + char *tmp = (char *) ALIGN(_tmp, 128); + volatile unsigned short *buf = (volatile unsigned short *) &tmp[0]; + unsigned int size = 128, tagid; + unsigned int offset; + addr64 ea64; + unsigned int oldtmask; + unsigned int tagmask; + + tagid = mfc_tag_reserve(); + + tagmask = 1 << (tagid & 31); + + ea64.ull = ALIGN128_EA(cond); + offset = OFFSET128_EA_U16(cond); + + MFC_DMA(buf, ea64, size, tagid & 31, MFC_GET_CMD); + oldtmask = spu_readch(MFC_RdTagMask); + spu_writech(MFC_WrTagMask, tagmask); + spu_writech(MFC_WrTagUpdate, MFC_TAG_UPDATE_ANY); + spu_readch(MFC_RdTagStat); + + /* this is still just one word. since buf is of type + * short, we fit both counts into one word. */ + buf[offset] = 0; + buf[offset+1] = 0; + MFC_DMA(buf, ea64, size, (tagid & 31), MFC_PUT_CMD); + spu_writech(MFC_WrTagMask, tagmask); + spu_writech(MFC_WrTagUpdate, MFC_TAG_UPDATE_ANY); + spu_readch(MFC_RdTagStat); + spu_writech(MFC_WrTagMask, oldtmask); + mfc_tag_release (tagid); +} + + + +#endif /* _SPU_COND_INIT_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/cond_signal.h b/gcell/src/ibm/sync/spu_source/cond_signal.h new file mode 100644 index 000000000..a035d2875 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/cond_signal.h @@ -0,0 +1,88 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_COND_SIGNAL_H_ +#define _SPU_COND_SIGNAL_H_ +#include <stdio.h> +#include "sync_utils.h" +#include "cond.h" +#include "atomic.h" +#include <spu_mfcio.h> + +/* + * _cond_signal: signalling any of the waiting threads to wake up. + */ +static __inline void _cond_signal(cond_ea_t cond) +{ + char _tmp[256]; + char *tmp = (char *) ALIGN(_tmp, 128); + volatile unsigned short *buf = (volatile unsigned short *) &tmp[0]; + unsigned int size = 128, tagid = 0; + u32 offset; + addr64 ea64; + int status; + + ea64.ull = ALIGN128_EA(cond); + offset = OFFSET128_EA_U16(cond); + + do { + MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD); + (void)spu_readch(MFC_RdAtomicStat); + + /* Check for waiting threads. + */ + if (buf[offset] != buf[offset+1]) { + /* Increment the signaled count to release the next waiting + * thread. + */ + buf[offset]++; + + MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLC_CMD); + status = spu_readch(MFC_RdAtomicStat); + } else { + /* Nobody is waiting, do nothing. + */ + status = 0; + } + } while (status); +} + + +#endif /* _SPU_COND_SIGNAL_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/cond_wait.h b/gcell/src/ibm/sync/spu_source/cond_wait.h new file mode 100644 index 000000000..cf4b880f5 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/cond_wait.h @@ -0,0 +1,103 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_COND_WAIT_H_ +#define _SPU_COND_WAIT_H_ +#include <stdio.h> +#include "sync_irq.h" +#include "sync_utils.h" +#include "mutex_lock.h" +#include "mutex_unlock.h" +#include "cond.h" +#include <spu_mfcio.h> + +static __inline void _cond_wait (cond_ea_t cond, mutex_ea_t mutex) +{ + char _tmp[256]; + char *tmp = (char *) ALIGN(_tmp, 128); + volatile signed short *buf = (volatile signed short *) &tmp[0]; + unsigned int size = 128, tagid = 0; + int status; + unsigned int offset; + addr64 ea64; + signed short delta, cur_delta, signaled_cnt; + + ea64.ull = ALIGN128_EA(cond); + offset = OFFSET128_EA_U16(cond); + + /* increment the waiting halfword of the condition variable. + */ + do { + MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD); + (void)spu_readch(MFC_RdAtomicStat); + + buf[offset+1]++; + + MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLC_CMD); + status = spu_readch(MFC_RdAtomicStat); + } while (status); + + _mutex_unlock(mutex); + + /* keep track of the change in count needed to be signaled. This + * is delta. + */ + signaled_cnt = buf[offset]; + delta = buf[offset+1] - signaled_cnt; + if (delta < 0) delta = -delta; + + while (1) { + MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD); + (void)spu_readch(MFC_RdAtomicStat); + + cur_delta = buf[offset] - signaled_cnt; + if (cur_delta < 0) cur_delta = -cur_delta; + + + if (cur_delta >= delta) { + /* the counts indicate that this thread has been signaled. + */ + break; + } + } + _mutex_lock (mutex); +} + +#endif /* _SPU_COND_WAIT_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/init_completion.h b/gcell/src/ibm/sync/spu_source/init_completion.h new file mode 100644 index 000000000..bf93e72af --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/init_completion.h @@ -0,0 +1,82 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_INIT_COMPLETION_H_ +#define _SPU_INIT_COMPLETION_H_ + +#include "sync_utils.h" +#include <spu_mfcio.h> +#include "completion.h" + +/** + * completion_init - initialize completion variable. + * @completion: handle to effective address of completion variable. + * + * Description: Initialize a completion variable to false. + */ +static __inline void _init_completion(completion_ea_t completion) +{ + DECL_COMPLETION_VARS(); + u32 oldtmask, tagmask; + + tagid = mfc_tag_reserve(); + tagmask = 1 << (tagid & 31); + + ea64.ull = ALIGN128_EA(completion); + offset = OFFSET128_EA_U32(completion); + + MFC_DMA(buf, ea64, size, tagid & 31, MFC_GET_CMD); + oldtmask = spu_readch(MFC_RdTagMask); + spu_writech(MFC_WrTagMask, tagmask); + spu_writech(MFC_WrTagUpdate, MFC_TAG_UPDATE_ANY); + spu_readch(MFC_RdTagStat); + + buf[offset] = 0; + MFC_DMA(buf, ea64, size, tagid & 31, MFC_PUT_CMD); + spu_writech(MFC_WrTagMask, tagmask); + spu_writech(MFC_WrTagUpdate, MFC_TAG_UPDATE_ANY); + spu_readch(MFC_RdTagStat); + spu_writech(MFC_WrTagMask, oldtmask); + mfc_tag_release(tagid); +} + + + +#endif /* _SPU_INIT_COMPLETION_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/libsync.h b/gcell/src/ibm/sync/spu_source/libsync.h new file mode 100644 index 000000000..48cc722bd --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/libsync.h @@ -0,0 +1,116 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_LIB_SYNC_H_ +#define _SPU_LIB_SYNC_H_ +#include "sync_utils.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned long long atomic_ea_t; + +extern void atomic_set(atomic_ea_t v, int val); +extern void atomic_add(int a, atomic_ea_t v); +extern void atomic_sub(int a, atomic_ea_t v); +extern void atomic_inc(atomic_ea_t v); +extern void atomic_dec(atomic_ea_t v); + +extern int atomic_read(atomic_ea_t v); +extern int atomic_add_return(int a, atomic_ea_t v); +extern int atomic_sub_return(int a, atomic_ea_t v); +extern int atomic_inc_return(atomic_ea_t v); +extern int atomic_dec_return(atomic_ea_t v); +extern int atomic_sub_and_test(int a, atomic_ea_t v); +extern int atomic_dec_and_test(atomic_ea_t v); +extern int atomic_dec_if_positive(atomic_ea_t v); + +typedef unsigned long long mutex_ea_t; + +extern void mutex_init(mutex_ea_t lock); +extern void mutex_lock(mutex_ea_t lock); +extern int mutex_trylock(mutex_ea_t ea); +extern void mutex_unlock(mutex_ea_t lock); + + +typedef struct +{ + int num_threads_signal; /* the number of threads that are going to be waken up. + * There are 3 values possible for this parameter, 0, 1, + * or num_threads_waiting + */ + int num_threads_waiting; /* the number of threads that are waiting to be awaken + */ +} condition_variable_t __attribute__ ((aligned (128))); + +typedef eaddr_t cond_ea_t; /* a system memory 64 bit address that points to + * a valid condition_variable_t + */ + + +extern void cond_init (cond_ea_t cond); +extern void cond_signal (cond_ea_t cond); +extern void cond_broadcast (cond_ea_t cond); +extern void cond_wait (cond_ea_t cond, mutex_ea_t mutex); + +typedef unsigned long long completion_ea_t; + +extern void init_completion(completion_ea_t completion); +extern void wait_for_completion(completion_ea_t completion); +extern void complete(completion_ea_t completion); +extern void complete_all(completion_ea_t completion); + +#ifdef __SPU__ + /* Function only implemented for the SPU + */ + extern void read_lock(eaddr_t ea); + extern void read_unlock(eaddr_t ea); + extern int read_trylock(eaddr_t ea); + extern void write_lock(eaddr_t ea); + extern void write_unlock(eaddr_t ea); + extern int write_trylock(eaddr_t ea); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _SPU_LIB_SYNC_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/mutex.h b/gcell/src/ibm/sync/spu_source/mutex.h new file mode 100644 index 000000000..37f2b4d62 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/mutex.h @@ -0,0 +1,178 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_MUTEX_H_ +#define _SPU_MUTEX_H_ 1 + +#include "sync_utils.h" +#include "sync_irq.h" +#include <spu_mfcio.h> + +typedef eaddr_t mutex_ea_t; + +#define DECL_MUTEX_VARS() \ + char _tmp[256]; \ + char *tmp = (char *) ALIGN(_tmp, 128); \ + volatile s32 *buf = (volatile s32 *) &tmp[0]; \ + u32 size = 128, tagid = 0; \ + u32 offset; \ + addr64 ea64 + +/* RAW_TEST_AND_SET + * Macro implementing the test and set primitive. + * + * RAW_TEST_AND_SET(==, 1) used by spin_try_lock() + * RAW_TEST_AND_SET(>=, 1) used by read_try_lock() + * RAW_TEST_AND_SET(==, -1) used by write_try_lock() + */ +#define RAW_TEST_AND_SET(_RELOP_, _val) \ + ea64.ull = ALIGN128_EA(ea); \ + offset = OFFSET128_EA_U32(ea); \ + do { \ + MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD); \ + spu_readch(MFC_RdAtomicStat); \ + SET_HIT; \ + if (likely(buf[offset] _RELOP_ 0)) { \ + buf[offset] += _val; \ + MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLC_CMD); \ + status = spu_readch(MFC_RdAtomicStat); \ + ret_val = 1; \ + } else { \ + MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLC_CMD); \ + spu_readch(MFC_RdAtomicStat); \ + status = ret_val = 0; \ + break; \ + } \ + } while (status != 0) + +/* RAW_SPINLOCK + * Macro implementing the spinlock primitive. + * + * RAW_SPINLOCK(==, 1) used by spin_lock() + * RAW_SPINLOCK(>=, 1) used by read_lock() + * RAW_SPINLOCK(==, -1) used by write_lock() + */ + + +#define RAW_SPINLOCK(_RELOP_, _val) \ + ea64.ull = ALIGN128_EA(ea); \ + offset = OFFSET128_EA_U32(ea); \ + do { \ + MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD); \ + spu_readch(MFC_RdAtomicStat); \ + SET_HIT; \ + status = 1; \ + if (likely(buf[offset] _RELOP_ 0)) { \ + buf[offset] += _val; \ + MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLC_CMD); \ + status = spu_readch(MFC_RdAtomicStat); \ + } \ + } while (status != 0); + + +static inline void _lock_init(eaddr_t ea) +{ + DECL_MUTEX_VARS(); + u32 oldtmask, tagmask; + + tagid = mfc_tag_reserve(); + + tagmask = 1 << (tagid & 31); + + /* __lock_init + * Internal routine to initialize a spinlock or + * reader/writer lock. + */ + ea64.ull = ALIGN128_EA(ea); + offset = OFFSET128_EA_U32(ea); + MFC_DMA(buf, ea64, size, tagid & 31, MFC_GET_CMD); + oldtmask = spu_readch(MFC_RdTagMask); + spu_writech(MFC_WrTagMask, tagmask); + spu_writech(MFC_WrTagUpdate, MFC_TAG_UPDATE_ANY); + spu_readch(MFC_RdTagStat); + + buf[offset] = 0; + MFC_DMA(buf, ea64, size, tagid & 31, MFC_PUT_CMD); + spu_writech(MFC_WrTagMask, tagmask); + spu_writech(MFC_WrTagUpdate, MFC_TAG_UPDATE_ANY); + spu_readch(MFC_RdTagStat); + spu_writech(MFC_WrTagMask, oldtmask); + mfc_tag_release(tagid); +} + +static inline void _spin_lock(eaddr_t ea) +{ + DECL_MUTEX_VARS(); + s32 status; + + /* _spin_lock + * Internal routine to acquire spinlock. + */ +/* non trace - no hit/miss indicator */ +#define SET_HIT + RAW_SPINLOCK(==, 1); +} + +#ifdef LIBSYNC_TRACE +static inline s32 _spin_lock_trace(eaddr_t ea) +{ + DECL_MUTEX_VARS(); + s32 status = 0; +/* trace - need hit/miss indicator */ +#undef SET_HIT +#define SET_HIT if (status == 0) hit = buf[offset] + s32 hit; + + hit = 0; + /* _spin_lock_trace for trace + * Internal routine to acquire spinlock. + */ + RAW_SPINLOCK(==, 1); + + return hit; + +#undef SET_HIT +#define SET_HIT +} + +#endif /* LIBSYNC_TRACE */ + + +#endif /* SPU_MUTEX_H */ diff --git a/gcell/src/ibm/sync/spu_source/mutex_init.h b/gcell/src/ibm/sync/spu_source/mutex_init.h new file mode 100644 index 000000000..9bddb1456 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/mutex_init.h @@ -0,0 +1,64 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_MUTEX_INIT_H_ +#define _SPU_MUTEX_INIT_H_ + +#include "sync_utils.h" +#include "mutex.h" +#include "trace_libsync.h" + +/***************************************************************************/ +/** + * mutex_init - initialize the mutex by setting the value + * to 0. + * @lock: handle to effective address of lock variable. + * + * Description: Initialize a mutex. + */ +static __inline void _mutex_init(mutex_ea_t lock) +{ + _lock_init(lock); + + TRACE_MUTEX_INIT(lock); +} + + +#endif /* _SPU_MUTEX_INIT_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/mutex_lock.h b/gcell/src/ibm/sync/spu_source/mutex_lock.h new file mode 100644 index 000000000..63bdbc36a --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/mutex_lock.h @@ -0,0 +1,66 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_MUTEX_LOCK_H_ +#define _SPU_MUTEX_LOCK_H_ + +#include "sync_utils.h" +#include "mutex.h" +#include "trace_libsync.h" + +static __inline void _mutex_lock(mutex_ea_t ea) +{ + +#ifdef LIBSYNC_TRACE + s32 miss = 0; + + TRACE_MUTEX_LOCK_ENTRY(interval); + miss = _spin_lock_trace(ea); + TRACE_MUTEX_LOCK_EXIT(interval, ea, miss); + +#else /* LIBSYNC_TRACE */ + + _spin_lock(ea); + +#endif /* LIBSYNC_TRACE */ + +} + +#endif /* _SPU_MUTEX_LOCK_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/mutex_trylock.h b/gcell/src/ibm/sync/spu_source/mutex_trylock.h new file mode 100644 index 000000000..3c8df4662 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/mutex_trylock.h @@ -0,0 +1,70 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_MUTEX_TRYLOCK_H_ +#define _SPU_MUTEX_TRYLOCK_H_ + +#include "sync_utils.h" +#include "mutex.h" +#include "trace_libsync.h" + +/** + * mutex_trylock - acquire a lock, or return immediately. + * @ea: handle to effective address of lock variable. + * + * Description: Acquire a lock, or return immediately + * without polling for availability. + * + * Context: The application should not call this interface + * from a tight loop!! Use spin_lock() instead. + */ +static __inline int _mutex_trylock(mutex_ea_t ea) +{ + DECL_MUTEX_VARS(); + s32 status, ret_val; + + RAW_TEST_AND_SET(==, 1); + + TRACE_MUTEX_TRYLOCK(ea, ret_val); + + return ret_val; +} + +#endif /* _SPU_MUTEX_TRYLOCK_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/mutex_unlock.h b/gcell/src/ibm/sync/spu_source/mutex_unlock.h new file mode 100644 index 000000000..87d6bbaef --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/mutex_unlock.h @@ -0,0 +1,59 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_MUTEX_UNLOCK_H_ +#define _SPU_MUTEX_UNLOCK_H_ + +#include "sync_utils.h" +#include "mutex.h" +#include "atomic.h" +#include "trace_libsync.h" + +static __inline void _mutex_unlock(mutex_ea_t ea) +{ + int ret_val; + + ATOMIC_OP((atomic_ea_t)ea, 0, 1, ret_val); + + TRACE_MUTEX_UNLOCK(ea); +} + + +#endif /* _SPU_MUTEX_UNLOCK_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/read_lock.h b/gcell/src/ibm/sync/spu_source/read_lock.h new file mode 100644 index 000000000..0e1d97182 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/read_lock.h @@ -0,0 +1,66 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_READ_LOCK_H_ +#define _SPU_READ_LOCK_H_ + +#include "sync_utils.h" +#include "mutex.h" + +/** + * read_lock - acquire reader lock, or spin until available. + * @ea: handle to effective address of lock variable. + * + * Description: Acquire a non-exclusive reader lock, or spin + * until available. The only restriction here is that @ea + * must be word aligned. + * + * Context: This routine should not be called if SPU + * asynchronous interrupts are enabled. + */ +static __inline void _read_lock(eaddr_t ea) +{ + DECL_MUTEX_VARS(); + s32 status; + + RAW_SPINLOCK(>=, 1); +} + +#endif /* _SPU_READ_LOCK_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/read_trylock.h b/gcell/src/ibm/sync/spu_source/read_trylock.h new file mode 100644 index 000000000..d03278351 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/read_trylock.h @@ -0,0 +1,71 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_READ_TRYLOCK_H_ +#define _SPU_READ_TRYLOCK_H_ + +#include "sync_utils.h" +#include "mutex.h" + +/** + * read_trylock - acquire a reader lock, or return immediately. + * @ea: handle to effective address of lock variable. + * + * Acquire a non-exclusive reader lock, or return + * immediately. The only restriction here is that + * @ea must be word aligned. + * + * Returns 1 on success, or 0 on failure. + * + * Context: The application should not call this interface + * from a tight loop!! Use read_lock() instead. + */ +static __inline int _read_trylock(eaddr_t ea) +{ + DECL_MUTEX_VARS(); + s32 status, ret_val; + + RAW_TEST_AND_SET(>=, 1); + + return ret_val; +} + + +#endif /* _SPU_READ_TRYLOCK_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/read_unlock.h b/gcell/src/ibm/sync/spu_source/read_unlock.h new file mode 100644 index 000000000..f011550e5 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/read_unlock.h @@ -0,0 +1,88 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_READ_UNLOCK_H_ +#define _SPU_READ_UNLOCK_H_ + +#include "sync_utils.h" +#include "mutex.h" +#include <spu_mfcio.h> + + +/** + * read_unlock - release reader lock. + * @ea: handle to effective address of lock variable. + * + * Description: Release a reader lock. The only restriction + * here is that @ea must be word aligned. + * + * Context: This routine should be used when interrupts + * do not need to be re-enabled --either because interrupts + * are not being used, or because the application will take + * steps to re-enable them later. + */ +static __inline void _read_unlock(eaddr_t ea) +{ + DECL_MUTEX_VARS(); + s32 status; + + /* _read_unlock + * + * Reader locks must use PUTLLC when releasing, instead of + * the more traditional PUTLLUC because of the non-exclusive + * nature of the lock. The reason for this is that other + * readers may have incremented the counter, and we don't + * want to corrupt it by blindly issuing PUTLLUC!! + */ + ea64.ull = ALIGN128_EA(ea); + offset = OFFSET128_EA_U32(ea); + do { + MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD); + spu_readch(MFC_RdAtomicStat); + + buf[offset] -= 1; + MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLC_CMD); + status = spu_readch(MFC_RdAtomicStat); + } while (status != 0); + +} + + +#endif /* _SPU_READ_UNLOCK_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/rwlock_init.h b/gcell/src/ibm/sync/spu_source/rwlock_init.h new file mode 100644 index 000000000..6b05533bb --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/rwlock_init.h @@ -0,0 +1,60 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_RWLOCK_INIT_H_ +#define _SPU_RWLOCK_INIT_H_ + +#include "sync_utils.h" +#include "mutex.h" + +/** + * rwlock_init - initialize a reader/writer lock. + * @ea: handle to effective address of lock variable. + * + * Description: Initialize a reader/writer lock. + */ +static __inline void _rwlock_init(eaddr_t rwlock) +{ + _lock_init(rwlock); +} + + + +#endif /* _SPU_RWLOCK_INIT_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/sync_irq.h b/gcell/src/ibm/sync/spu_source/sync_irq.h new file mode 100644 index 000000000..feae65e50 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/sync_irq.h @@ -0,0 +1,76 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +/* + * irq.h - SPU interrupt management facilities. + * + * These utilities help an "interrupt aware" library to manage + * state of SPU interrupts. + */ + +#ifndef __SPU_IRQ_H__ +#define __SPU_IRQ_H__ + +#include <spu_intrinsics.h> +#include "sync_utils.h" + +static inline u32 irq_mask(u32 newmask) +{ + u32 old, tmp = 0; + + /* irq_mask + * Set the interrupt mask to the newmask value, + * and return its previous setting. Will + * detect and discard potential phantom + * events. + */ + + old = spu_readch(SPU_RdEventMask); + spu_writech(SPU_WrEventMask, tmp); + if (spu_readchcnt(SPU_RdEventStat)) { + tmp = spu_readch(SPU_RdEventStat); + spu_writech(SPU_WrEventAck, tmp); + } + spu_writech(SPU_WrEventMask, newmask); + + return old; +} + +#endif /* __SPU_IRQ_H__ */ diff --git a/gcell/src/ibm/sync/spu_source/sync_utils.h b/gcell/src/ibm/sync/spu_source/sync_utils.h new file mode 100644 index 000000000..516b41f74 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/sync_utils.h @@ -0,0 +1,103 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +/* + * sync_utils.h - SPU sync-library internal utilities. + * + * These utilities are used internally by the SPU sync library. + */ +#ifndef __SPU_SYNC_UTILS_H__ +#define __SPU_SYNC_UTILS_H__ + +#include <spu_intrinsics.h> + +typedef unsigned int u32; +typedef signed int s32; +typedef unsigned long long u64; +typedef unsigned long long eaddr_t; + + +typedef union { + u64 ull; + u32 ui[2]; +} addr64; + +#ifndef likely +#define likely(_c) \ + __builtin_expect((_c), 1) +#define unlikely(_c) \ + __builtin_expect((_c), 0) +#endif + +#define ALLOCA(_nbytes, _size) \ + alloca((_nbytes) + (_size)-1) + +#define ALIGN(_ptr, _size) \ + ((((u32) _ptr) + (_size)-1) & ~((_size)-1)) + +#define ALIGN128_EA(_ull) \ + ((_ull) & ~(127ULL)) +/* +#define OFFSET128_EA(_ull, _type) \ + (((_ull) & 127ULL) / sizeof(_type)) + */ + +#define OFFSET128_EA_U32(_ull) \ + (((_ull) & 127ULL) >> 2) + +#define OFFSET128_EA_U16(_ull) \ + (((_ull) & 127ULL) >> 1) + +#define MFC_DMA(_ls, _ea, _sz, _tg, _cmd) \ + spu_mfcdma64(_ls, _ea.ui[0], _ea.ui[1], _sz, _tg, _cmd) + +#define MFC_SYNC() { \ + u32 _tagid = 0; \ + spu_writech(mfc_tag_id, _tagid); \ + spu_writech(mfc_cmd_queue, MFC_SYNC_CMD); \ +} + +#define MFC_EIEIO() { \ + u32 _tagid = 0; \ + spu_writech(mfc_tag_id, _tagid); \ + spu_writech(mfc_cmd_queue, MFC_EIEIO_CMD); \ +} + +#endif /* __SPU_SYNC_UTILS_H__ */ diff --git a/gcell/src/ibm/sync/spu_source/trace_libsync.h b/gcell/src/ibm/sync/spu_source/trace_libsync.h new file mode 100644 index 000000000..47887c9dc --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/trace_libsync.h @@ -0,0 +1,117 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2007 */ +/* International Business Machines Corporation */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef __LIBSYNC_SPU_TRACEHOOKS_H__ +#define __LIBSYNC_SPU_TRACEHOOKS_H__ + +#ifdef LIBSYNC_TRACE + +#include <trace_events.h> + +/* + * last parameter in the trace_even and trace_interval_entry call is + * the stack level to report the PC in the trace record. so 0 means + * the PC of the current frame, 1 means the PC of the caller, etc. + * there's a dilemma here - these macros are included in the inline + * _mutex calls which get called from the (created during build) + * mutex functions in the mutex .c files. in that case, the level + * should be 1 - we don't want the PC of where in the mutex function + * the trace call is happening, we want the PC of whomever is calling + * the mutex function. + * + * but.. an app can call the inline functions - it can #include the + * appropriate libsync mutex .h files, and call the inlined _mutex + * function in their code. in that case, the appropriate level for the + * trace calls would be 0 - the user would want to know where in their + * code the call to the _mutex function is. + * + * so, we'll assume _LEVEL of 0 which is what the inline funtions need. + * when we build the files for libsync, we'll do a -D_LEVEL=1 + */ +#ifndef _LEVEL +#define _LEVEL 0 +#endif + + +#define TRACE_EVENT_MUTEX_INIT 0x0403 + +#define TRACE_MUTEX_INIT(lock) { \ + trace_payload_t payload; \ + payload.dword[0]=(unsigned long)lock; \ + trace_event(TRACE_EVENT_MUTEX_INIT, 1, &payload, "Event=%d, lock=0x%x", _LEVEL); \ +} + +#define TRACE_EVENT_MUTEX_LOCK 0x0503 + +#define TRACE_MUTEX_LOCK_ENTRY(_INTERVAL) \ +trace_interval_p _INTERVAL = trace_interval_entry(TRACE_EVENT_MUTEX_LOCK, _LEVEL) + +#define TRACE_MUTEX_LOCK_EXIT(_INTERVAL,lock,miss) { \ + trace_payload_t payload; \ + payload.dword[0]=(unsigned long)lock; \ + payload.word[2]=(unsigned int)miss; \ + trace_interval_exit(_INTERVAL, 2, &payload, "Event=%d, lock=0x%x, miss=0x%x"); \ +} + +#define TRACE_EVENT_MUTEX_TRYLOCK 0x0603 + +#define TRACE_MUTEX_TRYLOCK(lock,ret_val) { \ + trace_payload_t payload; \ + payload.dword[0]=(unsigned long)lock; \ + payload.word[2]=(unsigned int)ret_val; \ + trace_event(TRACE_EVENT_MUTEX_TRYLOCK, 2, &payload, "Event=%d, lock=0x%x, ret_val=0x%x", _LEVEL); \ +} + +#define TRACE_EVENT_MUTEX_UNLOCK 0x0703 + +#define TRACE_MUTEX_UNLOCK(lock) { \ + trace_payload_t payload; \ + payload.dword[0]=(unsigned long)lock; \ + trace_event(TRACE_EVENT_MUTEX_UNLOCK, 1, &payload, "Event=%d, lock=0x%x", _LEVEL); \ +} + +#else /* LIBSYNC_TRACE */ + +#define TRACE_MUTEX_INIT(lock) +#define TRACE_MUTEX_LOCK_ENTRY(_INTERVAL) +#define TRACE_MUTEX_LOCK_EXIT(_INTERVAL,lock,miss) +#define TRACE_MUTEX_TRYLOCK(lock,ret_val) +#define TRACE_MUTEX_UNLOCK(lock) + +#endif /* LIBSYNC_TRACE */ + +#endif /* __LIBSYNC_SPU_TRACEHOOKS_H__ */ diff --git a/gcell/src/ibm/sync/spu_source/wait_for_completion.h b/gcell/src/ibm/sync/spu_source/wait_for_completion.h new file mode 100644 index 000000000..ea7bdbe6d --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/wait_for_completion.h @@ -0,0 +1,82 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_WAIT_FOR_COMPLETION_H_ +#define _SPU_WAIT_FOR_COMPLETION_H_ + +#include "sync_utils.h" +#include <spu_mfcio.h> +#include "sync_irq.h" +#include "completion.h" + +/* _wait_for_completion + * Internal routine to wait for completion to + * become true (!0). When completion is false, + * uses lock line reservation lost event to + * sleep until the variable has been changed. + */ +static __inline void _wait_for_completion(completion_ea_t completion) +{ + DECL_COMPLETION_VARS(); + s32 status; + + status = 1; + + ea64.ull = ALIGN128_EA(completion); + offset = OFFSET128_EA_U32(completion); + do { + MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD); + spu_readch(MFC_RdAtomicStat); + /* if the completion variable has been set elsewhere + * (a signal or broadcast function has been called + * then we get out of the loop, and reset the variable */ + if (likely(buf[offset] != 0)) { + /* decrement the variable */ + buf[offset]--; + MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLC_CMD); + spu_readch(MFC_RdAtomicStat); + status = 0; + } + } while (status != 0); +} + + + +#endif /* _SPU_WAIT_FOR_COMPLETION_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/write_lock.h b/gcell/src/ibm/sync/spu_source/write_lock.h new file mode 100644 index 000000000..7af5175f0 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/write_lock.h @@ -0,0 +1,67 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_WRITE_LOCK_H_ +#define _SPU_WRITE_LOCK_H_ + +#include "sync_utils.h" +#include "mutex.h" + +/** + * write_lock - acquire writer lock, or spin until available. + * @ea: handle to effective address of lock variable. + * + * Description: Acquire an exclusive writer lock, + * or spin until available. The only restriction + * here is that @ea must be word aligned. + * + * Context: This routine should not be called if SPU + * asynchronous interrupts are enabled. + */ +static __inline void _write_lock(eaddr_t ea) +{ + DECL_MUTEX_VARS(); + s32 status; + + RAW_SPINLOCK(==, -1); +} + + +#endif /* _SPU_WRITE_LOCK_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/write_trylock.h b/gcell/src/ibm/sync/spu_source/write_trylock.h new file mode 100644 index 000000000..b3799b37e --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/write_trylock.h @@ -0,0 +1,72 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_WRITE_TRYLOCK_H_ +#define _SPU_WRITE_TRYLOCK_H_ + +#include "sync_utils.h" +#include "mutex.h" + +/** + * write_trylock - acquire a writer lock, or return immediately. + * @ea: handle to effective address of lock variable. + * + * Try to acquire an exclusive writer lock, or return + * immediately. The only restriction here is that @ea + * must be word aligned. + * + * Returns 1 on success, or 0 on failure. + * + * Caution: + * The application should not call this interface from a tight + * loop!! Use write_lock() instead. + */ +static __inline int _write_trylock(eaddr_t ea) +{ + DECL_MUTEX_VARS(); + s32 status, ret_val; + + RAW_TEST_AND_SET(==, -1); + + return ret_val; +} + + +#endif /* _SPU_WRITE_TRYLOCK_H_ */ diff --git a/gcell/src/ibm/sync/spu_source/write_unlock.h b/gcell/src/ibm/sync/spu_source/write_unlock.h new file mode 100644 index 000000000..25b24e181 --- /dev/null +++ b/gcell/src/ibm/sync/spu_source/write_unlock.h @@ -0,0 +1,69 @@ +/* -------------------------------------------------------------- */ +/* (C)Copyright 2001,2007, */ +/* International Business Machines Corporation, */ +/* Sony Computer Entertainment, Incorporated, */ +/* Toshiba Corporation, */ +/* */ +/* All Rights Reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* - Redistributions of source code must retain the above copyright*/ +/* notice, this list of conditions and the following disclaimer. */ +/* */ +/* - 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. */ +/* */ +/* - Neither the name of IBM Corporation 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ +/* -------------------------------------------------------------- */ +/* PROLOG END TAG zYx */ +#ifndef _SPU_WRITE_UNLOCK_H_ +#define _SPU_WRITE_UNLOCK_H_ + +#include "sync_utils.h" +#include "mutex.h" +#include <spu_mfcio.h> + +/** + * write_unlock - release writer lock. + * @rwlock: handle to effective address of lock variable. + * + * Release a single writer lock. + */ +static __inline void _write_unlock(eaddr_t rwlock) +{ + DECL_MUTEX_VARS(); + + ea64.ull = ALIGN128_EA(rwlock); + offset = OFFSET128_EA_U32(rwlock); + MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD); + spu_readch(MFC_RdAtomicStat); + + buf[offset] = 0; + MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLUC_CMD); + spu_readch(MFC_RdAtomicStat); +} + + +#endif /* _SPU_WRITE_UNLOCK_H_ */ diff --git a/gcell/src/include/Makefile.am b/gcell/src/include/Makefile.am new file mode 100644 index 000000000..1e65282d7 --- /dev/null +++ b/gcell/src/include/Makefile.am @@ -0,0 +1,39 @@ +# +# Copyright 2007,2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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 3, or (at your option) +# any later version. +# +# GNU Radio 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +include $(top_srcdir)/Makefile.common + +SUBDIRS = spu + +gcellinclude_HEADERS = \ + compiler.h \ + gc_atomic.h \ + gc_cdefs.h \ + gc_declare_proc.h \ + gc_jd_queue_data.h \ + gc_jd_queue.h \ + gc_jd_stack.h \ + gc_job_desc.h \ + gc_job_desc_private.h \ + gc_logging.h \ + gc_mbox.h \ + gc_spu_args.h \ + gc_types.h \ + memory_barrier.h diff --git a/gcell/src/include/compiler.h b/gcell/src/include/compiler.h new file mode 100644 index 000000000..74a9739f8 --- /dev/null +++ b/gcell/src/include/compiler.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_COMPILER_H +#define INCLUDED_COMPILER_H + +/*! + * \brief Compiler specific hackery. These are for GCC. + */ + +#define _AL8 __attribute__((aligned (8))) +#define _AL16 __attribute__((aligned (16))) +#define _AL128 __attribute__((aligned (128))) + +#ifndef likely +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) +#endif + +#ifndef offsetof +#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER) +#endif + + +#endif /* INCLUDED_COMPILER_H */ diff --git a/gcell/src/include/gc_atomic.h b/gcell/src/include/gc_atomic.h new file mode 100644 index 000000000..01737cd03 --- /dev/null +++ b/gcell/src/include/gc_atomic.h @@ -0,0 +1,29 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_GC_ATOMIC_H +#define INCLUDED_GC_ATOMIC_H + +#include <stdint.h> + +typedef uint32_t gc_atomic_t; + + +#endif /* INCLUDED_GC_ATOMIC_H */ diff --git a/gcell/src/include/gc_cdefs.h b/gcell/src/include/gc_cdefs.h new file mode 100644 index 000000000..93084bae4 --- /dev/null +++ b/gcell/src/include/gc_cdefs.h @@ -0,0 +1,34 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_GC_CDEFS_H +#define INCLUDED_GC_CDEFS_H + +/* C++ needs to know that types and declarations are C, not C++. */ +#ifdef __cplusplus +# define __GC_BEGIN_DECLS extern "C" { +# define __GC_END_DECLS } +#else +# define __GC_BEGIN_DECLS +# define __GC_END_DECLS +#endif + +#endif /* INCLUDED_GC_CDEFS_H */ diff --git a/gcell/src/include/gc_declare_proc.h b/gcell/src/include/gc_declare_proc.h new file mode 100644 index 000000000..37af5bab7 --- /dev/null +++ b/gcell/src/include/gc_declare_proc.h @@ -0,0 +1,64 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_GC_DECLARE_PROC_H +#define INCLUDED_GC_DECLARE_PROC_H + +#include <stdint.h> +#include <gc_job_desc.h> + +/* + * This is C, not C++ code... + * + * ...and is used by both PPE and SPE code + */ +__GC_BEGIN_DECLS + +#define GC_PROC_DEF_SECTION ".gcell.proc_def" + +typedef struct gc_proc_def { +#if defined(__SPU__) + gc_spu_proc_t proc; +#else + uint32_t proc; +#endif + char name[28]; +} _AL16 gc_proc_def_t; + + +#if defined(__SPU__) +/*! + * \brief Tell gcell about a SPU procedure + * + * \param _proc_ pointer to function (gc_spu_proc_t) + * \param _name_ the name of the procedure ("quoted string") + * + * This macro registers the given procedure with the gcell runtime. + * From the PPE, use gc_job_manager::lookup_proc to map \p _name_ to a gc_proc_id_t + */ +#define GC_DECLARE_PROC(_proc_, _name_) \ +static struct gc_proc_def \ + _GCPD_ ## _proc_ __attribute__((section(GC_PROC_DEF_SECTION), used)) = \ + { _proc_, _name_ } +#endif + +__GC_END_DECLS + +#endif /* INCLUDED_GC_DECLARE_PROC_H */ diff --git a/gcell/src/include/gc_jd_queue.h b/gcell/src/include/gc_jd_queue.h new file mode 100644 index 000000000..f5f8a1a0d --- /dev/null +++ b/gcell/src/include/gc_jd_queue.h @@ -0,0 +1,52 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_GC_JD_QUEUE_H +#define INCLUDED_GC_JD_QUEUE_H + +#include "gc_jd_queue_data.h" + +__GC_BEGIN_DECLS + +/*! + * \brief Initialize the queue to empty. + */ +void +gc_jd_queue_init(gc_jd_queue_t *q); + + +/*! + * \brief Add \p item to the tail of \p q. + */ +void +gc_jd_queue_enqueue(gc_jd_queue_t *q, gc_job_desc_t *item); + + +/*! + * \brief Remove and return item at head of queue, or 0 if queue is empty + */ +gc_job_desc_t * +gc_jd_queue_dequeue(gc_jd_queue_t *q); + +__GC_END_DECLS + + +#endif /* INCLUDED_GC_JD_QUEUE_H */ diff --git a/gcell/src/include/gc_jd_queue_data.h b/gcell/src/include/gc_jd_queue_data.h new file mode 100644 index 000000000..d48591bd2 --- /dev/null +++ b/gcell/src/include/gc_jd_queue_data.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_GC_JD_QUEUE_DATA_H +#define INCLUDED_GC_JD_QUEUE_DATA_H + +#include "gc_types.h" +#include "gc_job_desc.h" + +__GC_BEGIN_DECLS + +/*! + * \brief (Lock free someday...) queue for job descriptors + * + * This is the main data structure shared between PPEs and SPEs. + * It is used to enqueue work for SPEs. SPEs or PPEs may enqueue + * work. SPE's dequeue from here. + * + * FIXME make it lock free ;) For now, use a spin lock. + */ +typedef struct gc_jd_queue +{ + gc_eaddr_t head _AL16; + gc_eaddr_t tail _AL16; + uint32_t mutex; // libsync mutex (spin lock) +} gc_jd_queue_t; + + +__GC_END_DECLS + +#endif /* INCLUDED_GC_JD_QUEUE_DATA_H */ + + diff --git a/gcell/src/include/gc_jd_stack.h b/gcell/src/include/gc_jd_stack.h new file mode 100644 index 000000000..72e9435ce --- /dev/null +++ b/gcell/src/include/gc_jd_stack.h @@ -0,0 +1,70 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_GC_JD_STACK_H +#define INCLUDED_GC_JD_STACK_H + +#include "gc_types.h" +#include "gc_job_desc.h" + +__GC_BEGIN_DECLS + +/*! + * \brief Lock free stack for job descriptors (used for free list) + * + * This is aligned to a cache line, and fills the cache line, + * to avoid inadvertently losing reservations created with + * the load-and-reserve instructions. + */ + +typedef struct gc_jd_stack +{ + gc_eaddr_t top; + + // pad out to a full cache line + uint8_t _pad[128 - sizeof(gc_eaddr_t)]; +} _AL128 gc_jd_stack_t; + + +/*! + * \brief Initialize the stack to empty. + */ +void +gc_jd_stack_init(gc_jd_stack_t *stack); + + +/*! + * \brief Add \p item to the top of \p stack. + */ +void +gc_jd_stack_push(gc_jd_stack_t *stack, gc_job_desc_t *item); + + +/*! + * \brief pop and return top item on stack, or 0 if stack is empty + */ +gc_job_desc_t * +gc_jd_stack_pop(gc_jd_stack_t *stack); + +__GC_END_DECLS + + +#endif /* INCLUDED_GC_JD_STACK_H */ diff --git a/gcell/src/include/gc_job_desc.h b/gcell/src/include/gc_job_desc.h new file mode 100644 index 000000000..b79150678 --- /dev/null +++ b/gcell/src/include/gc_job_desc.h @@ -0,0 +1,213 @@ +/* -*- c -*- */ +/* + * Copyright 2007,2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_GC_JOB_DESC_H +#define INCLUDED_GC_JOB_DESC_H + +/*! + * This file contains the structures that are used to describe how to + * call "jobs" that execute on the SPEs. A "job" is a task, or piece of + * work that you want to run on an SPE. + * + * There is code running in the SPE that knows how to interpret + * these job descriptions. Thus, in most cases, the overhead + * of invoking these is very low. + * + * The whole "job idea" is SPE centric. At first pass, + * the PPE will be constructing jobs and enqueing them. + * However, there is nothing in the implementation that + * prohibits SPEs from creating their own jobs in the + * future. Also, there is nothing prohibiting SPE-to-SPE + * DMA's. + * + * SPE's dequeue and "pull" jobs to themselves, do the work, then + * notify the entity that submitted the job. + */ + +#include "gc_types.h" +#include "gc_job_desc_private.h" + +/* + * This is C, not C++ code... + * + * ...and is used by both PPE and SPE code + */ +__GC_BEGIN_DECLS + + +//! opaque ID that specifies which code to invoke on the SPE +typedef uint32_t gc_proc_id_t; +#define GCP_UNKNOWN_PROC ((gc_proc_id_t) -1) + + +//! final job status +typedef enum { + JS_OK, + JS_SHUTTING_DOWN, // job mananger is shutting down + JS_TOO_MANY_CLIENTS, // too many client threads + JS_UNKNOWN_PROC, // didn't recognize the procedure ID + JS_BAD_DIRECTION, // EA arg has invalid direction + JS_BAD_EAH, // not all EA args have the same high 32 address bits + JS_BAD_N_DIRECT, // too many direct args + JS_BAD_N_EA, // too many EA args + JS_ARGS_TOO_LONG, // total length of EA args exceeds limit + JS_BAD_JUJU, // misc problem: you're having a bad day + JS_BAD_JOB_DESC, // gc_job_desc was not allocated using mgr->alloc_job_desc() + +} gc_job_status_t; + +#define MAX_ARGS_DIRECT 8 // maximum number of args passed using "direct" method +#define MAX_ARGS_EA 8 // maximum number of args passed via EA memory (dma) + +/* + * We support two classes of arguments, + * "direct", which are contained in the gc_job_desc_args and + * "EA", which are copied in/out according to info in gc_job_desc_args + */ + +/*! + * \brief Tag type of "direct" argument + */ +typedef enum { + GCT_S32, + GCT_U32, + GCT_S64, + GCT_U64, + GCT_FLOAT, + GCT_DOUBLE, + GCT_FLT_CMPLX, + GCT_DBL_CMPLX, + GCT_EADDR, + +} gc_tag_t; + + +/*! + * \brief union for passing "direct" argument + */ +typedef union gc_arg_union +{ + int32_t s32; + uint32_t u32; + int64_t s64; + uint64_t u64; + float f; + double d; + //float complex cf; // 64-bits (C99) + //double complex cd; // 128-bits (C99) + gc_eaddr_t ea; // 64-bits +} _AL8 gc_arg_union_t; + + +/*! + * \brief "direct" input or output arguments + */ +typedef struct gc_job_direct_args +{ + uint32_t nargs; // # of "direct" args + gc_tag_t tag[MAX_ARGS_DIRECT] _AL16; // type of direct arg[i] + gc_arg_union_t arg[MAX_ARGS_DIRECT] _AL16; // direct argument values + +} _AL16 gc_job_direct_args_t; + + +// specifies direction for args passed in EA memory + +#define GCJD_DMA_GET 0x01 // in to SPE +#define GCJD_DMA_PUT 0x02 // out from SPE + +/*! + * \brief Description of args passed in EA memory. + * These are DMA'd between EA and LS as specified. + */ +typedef struct gc_job_ea_arg { + //! EA address of buffer + gc_eaddr_t ea_addr; + + //! GC_JD_DMA_* get arg or put arg + uint32_t direction; + + //! number of bytes to get + uint32_t get_size; + + //! number of bytes to put + uint32_t put_size; + +#if defined(__SPU__) + //! local store address (filled in by SPU runtime) + void *ls_addr; + uint32_t _pad[2]; +#else + uint32_t _pad[3]; +#endif + +} _AL16 gc_job_ea_arg_t; + + +typedef struct gc_job_ea_args { + uint32_t nargs; + gc_job_ea_arg_t arg[MAX_ARGS_EA]; + +} _AL16 gc_job_ea_args_t; + + +/*! + * \brief "job description" that is DMA'd to/from the SPE. + */ +typedef struct gc_job_desc +{ + gc_job_desc_private_t sys; // internals + gc_job_status_t status; // what happened (output) + gc_proc_id_t proc_id; // specifies which procedure to run + gc_job_direct_args_t input; // direct args to SPE + gc_job_direct_args_t output; // direct args from SPE + gc_job_ea_args_t eaa; // args passed via EA memory + +} _AL128 gc_job_desc_t; + + +/*! + * type of procedure invoked on spu + */ +typedef void (*gc_spu_proc_t)(const gc_job_direct_args_t *input, + gc_job_direct_args_t *output, + const gc_job_ea_args_t *eaa); + +#if !defined(__SPU__) + +static inline gc_job_desc_t * +ea_to_jdp(gc_eaddr_t ea) +{ + return (gc_job_desc_t *) ea_to_ptr(ea); +} + +static inline gc_eaddr_t +jdp_to_ea(gc_job_desc_t *item) +{ + return ptr_to_ea(item); +} + +#endif + + +__GC_END_DECLS + +#endif /* INCLUDED_GC_JOB_DESC_H */ diff --git a/gcell/src/include/gc_job_desc_private.h b/gcell/src/include/gc_job_desc_private.h new file mode 100644 index 000000000..1f76d862b --- /dev/null +++ b/gcell/src/include/gc_job_desc_private.h @@ -0,0 +1,39 @@ +/* -*- c -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_GC_JOB_DESC_PRIVATE_H +#define INCLUDED_GC_JOB_DESC_PRIVATE_H + +// #include <libsync.h> + +/*! + * \brief Implementation details we'd like to hide from the user. + */ +typedef struct gc_job_desc_private +{ + gc_eaddr_t next; // used to implement job queue and free list + uint16_t job_id; + uint16_t client_id; + uint32_t direction_union; // union of all gc_job_ea_arg.direction fields +} gc_job_desc_private_t; + +#endif /* INCLUDED_GC_JOB_PRIVATE_H */ + diff --git a/gcell/src/include/gc_logging.h b/gcell/src/include/gc_logging.h new file mode 100644 index 000000000..b98c283a2 --- /dev/null +++ b/gcell/src/include/gc_logging.h @@ -0,0 +1,166 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_GC_LOGGING_H +#define INCLUDED_GC_LOGGING_H + +#include <gc_types.h> +#include <string.h> + +__GC_BEGIN_DECLS + +typedef struct gc_log { + gc_eaddr_t base; // gc_log_entry_t * (16 byte aligned) + uint32_t nentries; // number of entries (power-of-2) +} gc_log_t; + +typedef struct gc_log_entry { + uint32_t seqno; // monotonic sequence number + uint32_t timestamp; // decrementer value (wraps every 53s on PS3) + uint16_t subsystem; // 0 to 255 reserved for system, user gets 256 and up + uint16_t event; + uint32_t info[5]; +} _AL16 gc_log_entry_t; + +#define GCL_SS_SYS 0 // lowest system reserved subsystem +#define GCL_SS_USER 256 // lowest user reserved subsystem + + +/* + * The resulting log files can be displayed using using: + * + * $ od -t x4 -w32 spu_log.00 | less + */ + + +#if defined(__SPU__) + +/*! + * System fills in seqno and timestamp. User is responsible for the rest. + */ + +void _gc_log_write(gc_log_entry_t entry); + +#ifdef ENABLE_GC_LOGGING +#define gc_log_write(entry) _gc_log_write(entry) +#else +#define gc_log_write(entry) do { } while (0) +#endif + +inline static void +gc_log_write0(int subsystem, int event) +{ + gc_log_entry_t e; + e.subsystem = subsystem; + e.event = event; + e.info[0] = 0; + e.info[1] = 0; + e.info[2] = 0; + e.info[3] = 0; + e.info[4] = 0; + gc_log_write(e); +} + +inline static void +gc_log_write1(int subsystem, int event, + uint32_t info0) +{ + gc_log_entry_t e; + e.subsystem = subsystem; + e.event = event; + e.info[0] = info0; + e.info[1] = 0; + e.info[2] = 0; + e.info[3] = 0; + e.info[4] = 0; + gc_log_write(e); +} + +inline static void +gc_log_write2(int subsystem, int event, + uint32_t info0, uint32_t info1) +{ + gc_log_entry_t e; + e.subsystem = subsystem; + e.event = event; + e.info[0] = info0; + e.info[1] = info1; + e.info[2] = 0; + e.info[3] = 0; + e.info[4] = 0; + gc_log_write(e); +} + +inline static void +gc_log_write3(int subsystem, int event, + uint32_t info0, uint32_t info1, uint32_t info2) +{ + gc_log_entry_t e; + e.subsystem = subsystem; + e.event = event; + e.info[0] = info0; + e.info[1] = info1; + e.info[2] = info2; + e.info[3] = 0; + e.info[4] = 0; + gc_log_write(e); +} + +inline static void +gc_log_write4(int subsystem, int event, + uint32_t info0, uint32_t info1, uint32_t info2, uint32_t info3) +{ + gc_log_entry_t e; + e.subsystem = subsystem; + e.event = event; + e.info[0] = info0; + e.info[1] = info1; + e.info[2] = info2; + e.info[3] = info3; + e.info[4] = 0; + gc_log_write(e); +} + +inline static void +gc_log_write5(int subsystem, int event, + uint32_t info0, uint32_t info1, uint32_t info2, uint32_t info3, uint32_t info4) +{ + gc_log_entry_t e; + e.subsystem = subsystem; + e.event = event; + e.info[0] = info0; + e.info[1] = info1; + e.info[2] = info2; + e.info[3] = info3; + e.info[4] = info4; + gc_log_write(e); +} + +/*! + * One time initialization called by system runtime + */ +void +_gc_log_init(gc_log_t log_info); + +#endif + +__GC_END_DECLS + +#endif /* INCLUDED_GC_LOGGING_H */ diff --git a/gcell/src/include/gc_mbox.h b/gcell/src/include/gc_mbox.h new file mode 100644 index 000000000..32b23c6fa --- /dev/null +++ b/gcell/src/include/gc_mbox.h @@ -0,0 +1,52 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_GC_MBOX_H +#define INCLUDED_GC_MBOX_H + +/* + * The PPE and SPE exchange a few 32-bit messages via mailboxes. + * All have a 4 bit opcode in the high bits. + * + * 3 2 1 + * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | op | arg | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + */ + +#define MK_MBOX_MSG(cmd, args) ((((cmd) & 0xf) << 28) | ((args) & 0x0fffffff)) +#define MBOX_MSG_OP(msg) (((msg) >> 28) & 0xf) +#define MBOX_MSG_ARG(msg) ((msg) & 0x0fffffff) + +// PPE to SPE (sent via SPE Read Inbound Mailbox) + +#define OP_EXIT 0x0 // exit now +#define OP_GET_SPU_BUFSIZE 0x1 + +// SPE to PPE (sent via SPE Write Outbound Interrupt Mailbox) + +#define OP_JOBS_DONE 0x2 // arg is 0 or 1, indicating which + // gc_completion_info_t contains the info +#define OP_SPU_BUFSIZE 0x3 // arg is max number of bytes + + +#endif /* INCLUDED_GC_MBOX_H */ diff --git a/gcell/src/include/gc_spu_args.h b/gcell/src/include/gc_spu_args.h new file mode 100644 index 000000000..f5a21227c --- /dev/null +++ b/gcell/src/include/gc_spu_args.h @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_GC_SPU_ARGS_H +#define INCLUDED_GC_SPU_ARGS_H + +#include <gc_types.h> +#include <gc_logging.h> + +// args passed to SPE at initialization time + +typedef struct gc_spu_args { + gc_eaddr_t queue; // address of job queue (gc_jd_queue_t *) + gc_eaddr_t comp_info[2]; // completion info (gc_comp_info_t *) + uint32_t spu_idx; // which spu we are: [0,nspus-1] + uint32_t nspus; // number of spus we're using + uint32_t proc_def_ls_addr; // LS addr of proc_def table + uint32_t nproc_defs; // number of proc_defs in table + gc_log_t log; // logging info +} _AL16 gc_spu_args_t; + + +#define GC_CI_NJOBS 62 // makes gc_comp_info 1 cache line long + +/*! + * \brief Used to return info to PPE on which jobs are completed. + * + * When each SPE is initalized, it is passed EA pointers to two of + * these structures. The SPE uses these to communicate which jobs + * that it has worked on are complete. The SPE notifies the PPE by + * sending an OP_JOBS_DONE message (see gc_mbox.h) with an argument of + * 0 or 1, indicating which of the two comp_info's to examine. The + * SPE sets the in_use flag to 1 before DMA'ing to the PPE. When the + * PPE is done with the structure, it must clear the in_use field to + * let the SPE know it can begin using it again. + */ +typedef struct gc_comp_info { + uint16_t in_use; // set by SPE, cleared by PPE when it's finished + uint16_t ncomplete; // number of valid job_id's + uint16_t job_id[GC_CI_NJOBS]; // job_id's of completed jobs +} _AL128 gc_comp_info_t; + +#endif /* INCLUDED_GC_SPU_ARGS_H */ diff --git a/gcell/src/include/gc_types.h b/gcell/src/include/gc_types.h new file mode 100644 index 000000000..9a4d0546e --- /dev/null +++ b/gcell/src/include/gc_types.h @@ -0,0 +1,63 @@ +/* -*- c -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_GC_TYPES_H +#define INCLUDED_GC_TYPES_H + +#include <stdint.h> +#include <gc_cdefs.h> +#include "compiler.h" + +__GC_BEGIN_DECLS + +#ifndef __cplusplus +typedef int bool; +#define true 1 +#define false 0 +#endif + +/*! + * \brief 64-bit integer type representing an effective address (EA) + * + * This type is always 64-bits, regardless of whether we're + * running in 32 or 64-bit mode. + */ +typedef uint64_t gc_eaddr_t; + +#if !defined(__SPU__) +static inline void * +ea_to_ptr(gc_eaddr_t ea) +{ + // in 32-bit mode we're tossing the top 32-bits. + return (void *) (uintptr_t) ea; +} + +static inline gc_eaddr_t +ptr_to_ea(void *p) +{ + // two steps to avoid compiler warning in 32-bit mode. + return (gc_eaddr_t) (uintptr_t) p; +} +#endif + +__GC_END_DECLS + +#endif /* INCLUDED_GC_TYPES_H */ diff --git a/gcell/src/include/memory_barrier.h b/gcell/src/include/memory_barrier.h new file mode 100644 index 000000000..b373ffd91 --- /dev/null +++ b/gcell/src/include/memory_barrier.h @@ -0,0 +1,66 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_MEMORY_BARRIER_H +#define INCLUDED_MEMORY_BARRIER_H + +/* + * powerpc memory barriers + * + * The sync instruction guarantees that all memory accesses initiated + * by this processor have been performed (with respect to all other + * mechanisms that access memory). The eieio instruction is a barrier + * providing an ordering (separately) for (a) cacheable stores and (b) + * loads and stores to non-cacheable memory (e.g. I/O devices). + * + * smp_mb() prevents loads and stores being reordered across this point. + * smp_rmb() prevents loads being reordered across this point. + * smp_wmb() prevents stores being reordered across this point. + * + * We have to use the sync instructions for smp_mb(), since lwsync + * doesn't order loads with respect to previous stores. Lwsync is + * fine for smp_rmb(), though. For smp_wmb(), we use eieio since it + * is only used to order updates to system memory. + * + * For details, see "PowerPC Virtual Environment Architecture, Book + * II". Especially Chapter 1, "Storage Model" and Chapter 3, "Storage + * Control Instructions." (site:ibm.com) + */ + +#include <ppu_intrinsics.h> + +static inline void smp_mb(void) +{ + __sync(); +} + +static inline void smp_rmb(void) +{ + __lwsync(); +} + +static inline void smp_wmb(void) +{ + __eieio(); +} + + +#endif /* INCLUDED_MEMORY_BARRIER_H */ diff --git a/gcell/src/include/spu/Makefile.am b/gcell/src/include/spu/Makefile.am new file mode 100644 index 000000000..d202336f7 --- /dev/null +++ b/gcell/src/include/spu/Makefile.am @@ -0,0 +1,25 @@ +# +# Copyright 2007,2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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 3, or (at your option) +# any later version. +# +# GNU Radio 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +include $(top_srcdir)/Makefile.common + +gcellspuinclude_HEADERS = \ + gc_delay.h \ + gc_jd_queue.h diff --git a/gcell/src/include/spu/gc_delay.h b/gcell/src/include/spu/gc_delay.h new file mode 100644 index 000000000..78f16fb28 --- /dev/null +++ b/gcell/src/include/spu/gc_delay.h @@ -0,0 +1,27 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_GC_DELAY_H +#define INCLUDED_GC_DELAY_H + +void gc_udelay(unsigned int usecs); +void gc_cdelay(unsigned int cpu_cycles); + +#endif /* INCLUDED_GC_DELAY_H */ diff --git a/gcell/src/include/spu/gc_jd_queue.h b/gcell/src/include/spu/gc_jd_queue.h new file mode 100644 index 000000000..f1ce1b3bd --- /dev/null +++ b/gcell/src/include/spu/gc_jd_queue.h @@ -0,0 +1,57 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_SPU_GC_JD_QUEUE_H +#define INCLUDED_SPU_GC_JD_QUEUE_H + +#include "gc_jd_queue_data.h" + +/* + * Declarations for SPU side of job queue interface + */ + +__GC_BEGIN_DECLS + +/*! + * \brief Remove and return item at head of queue. + * + * \param[in] q is EA address of queue structure. + * \param[out] item_ea is EA address of item at head of queue. + * \param[out] item is local store copy of item at head of queue. + * \returns false if the queue is empty, otherwise returns true + * and sets \p item_ea and DMA's job descriptor into \p item + */ +bool +gc_jd_queue_dequeue(gc_eaddr_t q, gc_eaddr_t *item_ea, gc_job_desc_t *item); + + +/*! + * \brief Get a line reservation on the queue + * + * \param[in] q is EA address of queue structure. + */ +void +gc_jd_queue_getllar(gc_eaddr_t q); + +__GC_END_DECLS + + +#endif /* INCLUDED_SPU_GC_JD_QUEUE_H */ diff --git a/gcell/src/lib/Makefile.am b/gcell/src/lib/Makefile.am new file mode 100644 index 000000000..2ccedc332 --- /dev/null +++ b/gcell/src/lib/Makefile.am @@ -0,0 +1,48 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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 3, or (at your option) +# any later version. +# +# GNU Radio 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +include $(top_srcdir)/Makefile.common + +SUBDIRS = spu runtime general procs . + +# generate libgcell.la from the convenience libraries in subdirs + +lib_LTLIBRARIES = libgcell.la libgcell-qa.la + +libgcell_la_SOURCES = +libgcell_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0 + +libgcell_qa_la_SOURCES = +libgcell_qa_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0 + +libgcell_la_LIBADD = \ + runtime/libruntime.la \ + -lspe2 \ + $(OMNITHREAD_LA) + +libgcell_qa_la_LIBADD = \ + runtime/libruntime-qa.la \ + $(CPPUNIT_LIBS) + + + + + + diff --git a/gcell/src/lib/general/Makefile.am b/gcell/src/lib/general/Makefile.am new file mode 100644 index 000000000..0e32ffc37 --- /dev/null +++ b/gcell/src/lib/general/Makefile.am @@ -0,0 +1,24 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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 3, or (at your option) +# any later version. +# +# GNU Radio 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +include $(top_srcdir)/Makefile.common + +# SUBDIRS = spu . + diff --git a/gcell/src/lib/procs/Makefile.am b/gcell/src/lib/procs/Makefile.am new file mode 100644 index 000000000..0e32ffc37 --- /dev/null +++ b/gcell/src/lib/procs/Makefile.am @@ -0,0 +1,24 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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 3, or (at your option) +# any later version. +# +# GNU Radio 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +include $(top_srcdir)/Makefile.common + +# SUBDIRS = spu . + diff --git a/gcell/src/lib/runtime/Makefile.am b/gcell/src/lib/runtime/Makefile.am new file mode 100644 index 000000000..3f2077c08 --- /dev/null +++ b/gcell/src/lib/runtime/Makefile.am @@ -0,0 +1,76 @@ +# +# Copyright 2007,2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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 3, or (at your option) +# any later version. +# +# GNU Radio 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +include $(top_srcdir)/Makefile.common + +# SUBDIRS = spu . + +IBM_PPU_SYNC_INCLUDES = -I$(top_srcdir)/gcell/src/ibm/sync/ppu_source + + +AM_CPPFLAGS = $(DEFINES) $(OMNITHREAD_INCLUDES) $(MBLOCK_INCLUDES) $(CPPUNIT_INCLUDES) \ + $(GCELL_INCLUDES) $(IBM_PPU_SYNC_INCLUDES) $(WITH_INCLUDES) + + +noinst_LTLIBRARIES = libruntime.la libruntime-qa.la + +libruntime_la_SOURCES = \ + gc_job_manager.cc \ + gc_job_manager_impl.cc \ + gc_jd_queue.c \ + gc_jd_stack.c \ + gc_proc_def_utils.cc + +libruntime_qa_la_SOURCES = \ + qa_lib.cc \ + qa_jd_queue.cc \ + qa_jd_stack.cc \ + qa_job_manager.cc + + +gcellinclude_HEADERS = \ + gc_job_manager.h + +noinst_HEADERS = \ + gc_client_thread_info.h \ + gc_job_manager_impl.h \ + gc_proc_def_utils.h \ + qa_jd_queue.h \ + qa_jd_stack.h \ + qa_job_manager.h \ + qa_lib.h + + +# This kruft is required to link the QA SPU executable into the PPE shared lib w/o warnings +gcell_qa.lo: ../spu/gcell_qa + ppu-embedspu -m32 -fpic gcell_qa ../spu/gcell_qa .libs/gcell_qa.o + @rm -f gcell_qa.lo + @echo "# gcell_qa.lo - a libtool object file" >> gcell_qa.lo + @echo "# Generated by ltmain.sh - GNU libtool 1.5.22 (1.1220.2.365 2005/12/18 22:14:06)" >> gcell_qa.lo + @echo "#" >> gcell_qa.lo + @echo "# Please DO NOT delete this file!" >> gcell_qa.lo + @echo "# It is necessary for linking the library." >> gcell_qa.lo + @echo "" >> gcell_qa.lo + @echo "pic_object='.libs/gcell_qa.o'" >> gcell_qa.lo + @echo "non_pic_object=none" >> gcell_qa.lo + +libruntime_qa_la_LIBADD = \ + gcell_qa.lo \ + libruntime.la diff --git a/gcell/src/lib/runtime/gc_client_thread_info.h b/gcell/src/lib/runtime/gc_client_thread_info.h new file mode 100644 index 000000000..fbb35d966 --- /dev/null +++ b/gcell/src/lib/runtime/gc_client_thread_info.h @@ -0,0 +1,81 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_GC_CLIENT_THREAD_INFO_H +#define INCLUDED_GC_CLIENT_THREAD_INFO_H + +#include <omnithread.h> +#include <boost/utility.hpp> + +enum gc_ct_state { + CT_NOT_WAITING, + CT_WAIT_ALL, + CT_WAIT_ANY, +}; + +/* + * \brief per client-thread data used by gc_job_manager + * + * "Client threads" are any threads that invoke methods on + * gc_job_manager. We use pthread_set_specific to store a pointer to + * one of these for each thread that comes our way. + */ +class gc_client_thread_info : boost::noncopyable { +public: + gc_client_thread_info() : + d_free(1), d_cond(&d_mutex), d_state(CT_NOT_WAITING), + d_jobs_done(0), d_njobs_waiting_for(0), + d_jobs_waiting_for(0){ } + + ~gc_client_thread_info() { + d_free = 1; + d_state = CT_NOT_WAITING; + d_jobs_done = 0; + d_njobs_waiting_for = 0; + d_jobs_waiting_for = 0; + } + + //! is this cti free? (1->free, 0->in use) + uint32_t d_free; + + //! which client info are we? + uint16_t d_client_id; + + //! hold this mutex to manipulate anything below here + omni_mutex d_mutex; + + //! signaled by event handler to wake client thread up + omni_condition d_cond; + + //! Is this client waiting? + gc_ct_state d_state; + + //! Jobs that have finished and not yet been waited for (bitvector) + unsigned long *d_jobs_done; + + //! # of jobs we're waiting for + unsigned int d_njobs_waiting_for; + + //! Jobs that client thread is waiting for + gc_job_desc **d_jobs_waiting_for; + +}; + +#endif /* INCLUDED_GC_CLIENT_THREAD_INFO_H */ diff --git a/gcell/src/lib/runtime/gc_jd_queue.c b/gcell/src/lib/runtime/gc_jd_queue.c new file mode 100644 index 000000000..b5cdcac9b --- /dev/null +++ b/gcell/src/lib/runtime/gc_jd_queue.c @@ -0,0 +1,78 @@ +/* -*- c -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "gc_jd_queue.h" +#include "memory_barrier.h" +#include <mutex_init.h> +#include <mutex_lock.h> +#include <mutex_unlock.h> + +void +gc_jd_queue_init(gc_jd_queue_t *q) +{ + _mutex_init(ptr_to_ea(&q->mutex)); + q->head = 0; + q->tail = 0; + smp_wmb(); +} + +void +gc_jd_queue_enqueue(gc_jd_queue_t *q, gc_job_desc_t *item) +{ + item->sys.next = 0; + _mutex_lock(ptr_to_ea(&q->mutex)); + smp_rmb(); // import barrier + + if (q->tail == 0){ // currently empty + q->tail = q->head = jdp_to_ea(item); + } + else { // not empty, append + ea_to_jdp(q->tail)->sys.next = jdp_to_ea(item); + q->tail = jdp_to_ea(item); + } + + smp_wmb(); // orders stores above before clearing of mutex + _mutex_unlock(ptr_to_ea(&q->mutex)); +} + +gc_job_desc_t * +gc_jd_queue_dequeue(gc_jd_queue_t *q) +{ + _mutex_lock(ptr_to_ea(&q->mutex)); + smp_rmb(); // import barrier + + gc_eaddr_t item_ea = q->head; + if (item_ea == 0){ // empty + _mutex_unlock(ptr_to_ea(&q->mutex)); + return 0; + } + + q->head = ea_to_jdp(item_ea)->sys.next; + if (q->head == 0) // now emtpy + q->tail = 0; + + gc_job_desc_t *item = ea_to_jdp(item_ea); + item->sys.next = 0; + + smp_wmb(); // orders stores above before clearing of mutex + _mutex_unlock(ptr_to_ea(&q->mutex)); + return item; +} diff --git a/gcell/src/lib/runtime/gc_jd_stack.c b/gcell/src/lib/runtime/gc_jd_stack.c new file mode 100644 index 000000000..0fffc0d1f --- /dev/null +++ b/gcell/src/lib/runtime/gc_jd_stack.c @@ -0,0 +1,108 @@ +/* -*- c -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "gc_jd_stack.h" +#include "memory_barrier.h" + + +void +gc_jd_stack_init(gc_jd_stack_t *stack) +{ + stack->top = 0; +} + + +#ifdef __powerpc64__ // 64-bit mode + +void +gc_jd_stack_push(gc_jd_stack_t *stack, gc_job_desc_t *item) +{ + gc_eaddr_t top; + gc_eaddr_t item_ea = ptr_to_ea(item); + unsigned int done; + + do { + top = __ldarx(&stack->top); + item->sys.next = top; + smp_wmb(); // order store of item->next before store of stack->top + done = __stdcx(&stack->top, item_ea); + } while (unlikely(done == 0)); +} + +gc_job_desc_t * +gc_jd_stack_pop(gc_jd_stack_t *stack) +{ + gc_eaddr_t s; + gc_eaddr_t t; + unsigned int done; + + do { + s = __ldarx(&stack->top); + if (s == 0) /* stack's empty */ + return 0; + t = ((gc_job_desc_t *) ea_to_ptr(s))->sys.next; + done = __stdcx(&stack->top, t); + } while (unlikely(done == 0)); + + return ea_to_ptr(s); +} + +#else // 32-bit mode + +/* + * In 32-bit mode, gc_eaddr's will have the top 32-bits zero. + * The ldarx/stdcx instructions aren't available in 32-bit mode, + * thus we use lwarx/stwcx on the low 32-bits of the 64-bit addresses. + * Since we're big-endian, the low 32-bits are at word offset 1. + */ +void +gc_jd_stack_push(gc_jd_stack_t *stack, gc_job_desc_t *item) +{ + gc_eaddr_t top; + unsigned int done; + + do { + top = __lwarx((int32_t *)(&stack->top) + 1); + item->sys.next = top; + smp_wmb(); // order store of item->sys.next before store of stack->top + done = __stwcx((int32_t *)(&stack->top) + 1, item); + } while (unlikely(done == 0)); +} + +gc_job_desc_t * +gc_jd_stack_pop(gc_jd_stack_t *stack) +{ + gc_eaddr_t s; + gc_eaddr_t t; + unsigned int done; + + do { + s = __lwarx((int32_t *)(&stack->top) + 1); + if (s == 0) /* stack's empty */ + return 0; + t = ((gc_job_desc_t *) ea_to_ptr(s))->sys.next; + done = __stwcx((int32_t *)(&stack->top) + 1, (uint32_t) t); + } while (unlikely(done == 0)); + + return ea_to_ptr(s); +} + +#endif diff --git a/gcell/src/lib/runtime/gc_job_manager.cc b/gcell/src/lib/runtime/gc_job_manager.cc new file mode 100644 index 000000000..edb52a5b7 --- /dev/null +++ b/gcell/src/lib/runtime/gc_job_manager.cc @@ -0,0 +1,54 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "gc_job_manager.h" +#include "gc_job_manager_impl.h" + +gc_job_manager * +gc_make_job_manager(const gc_jm_options *options) +{ + return new gc_job_manager_impl(options); +} + +gc_job_manager::gc_job_manager(const gc_jm_options *options) +{ + // nop +} + +gc_job_manager::~gc_job_manager() +{ + // nop +} + +void +gc_job_manager::set_debug(int debug) +{ + // nop +} + +int +gc_job_manager::debug() +{ + return 0; +} diff --git a/gcell/src/lib/runtime/gc_job_manager.h b/gcell/src/lib/runtime/gc_job_manager.h new file mode 100644 index 000000000..9c8e70bf8 --- /dev/null +++ b/gcell/src/lib/runtime/gc_job_manager.h @@ -0,0 +1,171 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_GC_JOB_MANAGER_H +#define INCLUDED_GC_JOB_MANAGER_H + +#include <boost/utility.hpp> +#include <vector> +#include <string> +#include <libspe2.h> +#include "gc_job_desc.h" + +class gc_job_manager; + +enum gc_wait_mode { + GC_WAIT_ANY, + GC_WAIT_ALL, +}; + +/* + * \brief Options that configure the job_manager. + * The default values are reasonable. + */ +struct gc_jm_options { + unsigned int max_jobs; // max # of job descriptors in system + unsigned int max_client_threads; // max # of client threads of job manager + unsigned int nspes; // how many SPEs shall we use? 0 -> all of them + bool gang_schedule; // shall we gang schedule? + bool use_affinity; // shall we try for affinity (FIXME not implmented) + bool enable_logging; // shall we log SPE events? + uint32_t log2_nlog_entries; // log2 of number of log entries (default is 12 == 4k) + spe_program_handle_t *program_handle; // program to load into SPEs + + gc_jm_options() : + max_jobs(0), max_client_threads(0), nspes(0), + gang_schedule(true), use_affinity(false), + enable_logging(false), log2_nlog_entries(12), + program_handle(0) + { + } +}; + + +/* + * \brief Create an instance of the job manager + */ +gc_job_manager * +gc_make_job_manager(const gc_jm_options *options = 0); + + +/*! + * \brief Abstract class that manages SPE jobs. + * + * There is typically a single instance derived from this class. + * It is safe to call its methods from any thread. + */ +class gc_job_manager : boost::noncopyable +{ +public: + gc_job_manager(const gc_jm_options *options = 0); + + virtual ~gc_job_manager(); + + /*! + * Stop accepting new jobs. Wait for existing jobs to complete. + * Return all managed SPE's to the system. + */ + virtual bool shutdown() = 0; + + /*! + * \brief Return number of SPE's currently allocated to job manager. + */ + virtual int nspes() const = 0; + + /*! + * \brief Return a pointer to a properly aligned job descriptor, + * or zero if none are available. + */ + virtual gc_job_desc *alloc_job_desc() = 0; + + /* + *! Free a job descriptor previously allocated with alloc_job_desc() + * + * \param[in] jd pointer to job descriptor to free. + */ + virtual void free_job_desc(gc_job_desc *jd) = 0; + + /*! + * \brief Submit a job for asynchronous processing on an SPE. + * + * \param[in] jd pointer to job description + * + * The caller must not read or write the job description + * or any of the memory associated with any indirect arguments + * until after calling wait_job. + * + * \returns true iff the job was successfully enqueued. + * If submit_job returns false, check jd->status for additional info. + */ + virtual bool submit_job(gc_job_desc *jd) = 0; + + /*! + * \brief Wait for job to complete. + * + * A thread may only wait for jobs which it submitted. + * + * \returns true if sucessful, else false. + */ + virtual bool + wait_job(gc_job_desc *jd) = 0; + + /*! + * \brief wait for 1 or more jobs to complete. + * + * \param[input] njobs is the length of arrays \p jd and \p done. + * \param[input] jd are the jobs that are to be waited for. + * \param[output] done indicates whether the corresponding job is complete. + * \param[input] mode indicates whether to wait for ALL or ANY of the jobs + * in \p jd to complete. + * + * A thread may only wait for jobs which it submitted. + * + * \returns number of jobs completed, or -1 if error. + */ + virtual int + wait_jobs(unsigned int njobs, + gc_job_desc *jd[], bool done[], gc_wait_mode mode) = 0; + + /*! + * Return the maximum number of bytes of EA arguments that may be + * copied to or from the SPE in a single job. The limit applies + * independently to the "get" and "put" args. + * \sa gc_job_desc_t, gc_job_ea_args_t + */ + virtual int ea_args_maxsize() = 0; + + /*! + * Return gc_proc_id_t associated with spu procedure \p proc_name if one + * exists, otherwise return GCP_UNKNOWN_PROC. + */ + virtual gc_proc_id_t lookup_proc(const std::string &proc_name) = 0; + + /*! + * Return a vector of all known spu procedure names. + */ + virtual std::vector<std::string> proc_names() = 0; + + virtual void set_debug(int debug); + virtual int debug(); +}; + + +#endif /* INCLUDED_GC_JOB_MANAGER_H */ diff --git a/gcell/src/lib/runtime/gc_job_manager_impl.cc b/gcell/src/lib/runtime/gc_job_manager_impl.cc new file mode 100644 index 000000000..13d8f0d97 --- /dev/null +++ b/gcell/src/lib/runtime/gc_job_manager_impl.cc @@ -0,0 +1,1274 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include <gc_job_manager_impl.h> +#include <gc_mbox.h> +#include <gc_proc_def_utils.h> + +#include <stdio.h> +#include <stdexcept> +#include <stdlib.h> +#include <atomic_dec_if_positive.h> +#include <memory_barrier.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + + +static const size_t CACHE_LINE_SIZE = 128; + +static const unsigned int DEFAULT_MAX_JOBS = 128; +static const unsigned int DEFAULT_MAX_CLIENT_THREADS = 64; + +// FIXME this really depends on the SPU code... +static const unsigned int MAX_TOTAL_INDIRECT_LENGTH = 16 * 1024; + + +static bool s_key_initialized = false; +static pthread_key_t s_client_key; + +static int s_worker_debug = 0; + +// custom deleter of gang_contexts for use with boost::shared_ptr +class gang_deleter { +public: + void operator()(spe_gang_context_ptr_t ctx) { + if (ctx){ + int r = spe_gang_context_destroy(ctx); + if (r != 0){ + perror("spe_gang_context_destroy"); + } + } + } +}; + +// custom deleter +class spe_program_handle_deleter { +public: + void operator()(spe_program_handle_t *program) { + if (program){ + int r = spe_image_close(program); + if (r != 0){ + perror("spe_image_close"); + } + } + } +}; + + +// custom deleter of anything that can be freed with "free" +class free_deleter { +public: + void operator()(void *p) { + free(p); + } +}; + + +/* + * Called when client thread is destroyed. + * We mark our client info free. + */ +static void +client_key_destructor(void *p) +{ + ((gc_client_thread_info *) p)->d_free = 1; +} + +/* + * Return pointer to cache-aligned chunk of storage of size size bytes. + * Throw if can't allocate memory. The storage should be freed + * with "free" when done. The memory is initialized to zero. + */ +static void * +aligned_alloc(size_t size, size_t alignment = CACHE_LINE_SIZE) +{ + void *p = 0; + if (posix_memalign(&p, alignment, size) != 0){ + perror("posix_memalign"); + throw std::runtime_error("memory"); + } + memset(p, 0, size); // zero the memory + return p; +} + +static bool +is_power_of_2(uint32_t x) +{ + return (x != 0) && !(x & (x - 1)); +} + +//////////////////////////////////////////////////////////////////////// + + +gc_job_manager_impl::gc_job_manager_impl(const gc_jm_options *options) + : d_debug(0), d_spu_args(0), + d_eh_cond(&d_eh_mutex), d_eh_thread(0), d_eh_state(EHS_INIT), + d_shutdown_requested(false), + d_client_thread(0), d_ea_args_maxsize(0), + d_proc_def(0), d_proc_def_ls_addr(0), d_nproc_defs(0) +{ + if (!s_key_initialized){ + int r = pthread_key_create(&s_client_key, client_key_destructor); + if (r != 0) + throw std::runtime_error("pthread_key_create"); + s_key_initialized = true; + } + + // ensure it's zero + pthread_setspecific(s_client_key, 0); + + if (options != 0) + d_options = *options; + + // provide the real default for those indicated with a zero + if (d_options.max_jobs == 0) + d_options.max_jobs = DEFAULT_MAX_JOBS; + if (d_options.max_client_threads == 0) + d_options.max_client_threads = DEFAULT_MAX_CLIENT_THREADS; + + if (d_options.program_handle == 0){ + fprintf(stderr, "gc_job_manager: options->program_handle must be non-zero\n"); + throw std::runtime_error("gc_job_manager: options->program_handle must be non-zero"); + } + + int ncpu_nodes = spe_cpu_info_get(SPE_COUNT_PHYSICAL_CPU_NODES, -1); + int nusable_spes = spe_cpu_info_get(SPE_COUNT_USABLE_SPES, -1); + + if (debug()){ + printf("cpu_nodes = %d\n", ncpu_nodes); + for (int i = 0; i < ncpu_nodes; i++){ + printf("node[%d].physical_spes = %2d\n", i, + spe_cpu_info_get(SPE_COUNT_PHYSICAL_SPES, i)); + printf("node[%d].usable_spes = %2d\n", i, + spe_cpu_info_get(SPE_COUNT_USABLE_SPES, i)); + } + } + + // clamp nspes + d_options.nspes = std::min(d_options.nspes, (unsigned int) MAX_SPES); + nusable_spes = std::min(nusable_spes, (int) MAX_SPES); + + // + // sanity check requested number of spes. + // + if (d_options.nspes == 0) // use all of them + d_options.nspes = nusable_spes; + else { + if (d_options.nspes > (unsigned int) nusable_spes){ + fprintf(stderr, + "gc_job_manager: warning: caller requested %d spes. There are only %d available.\n", + d_options.nspes, nusable_spes); + if (d_options.gang_schedule){ + // If we're gang scheduling we'll never get scheduled if we + // ask for more than are available. + throw std::out_of_range("gang_scheduling: not enough spes available"); + } + else { // FIXME clamp to usable. problem on PS3 when overcommited + fprintf(stderr, "gc_job_manager: clamping nspes to %d\n", nusable_spes); + d_options.nspes = nusable_spes; + } + } + } + + if (d_options.use_affinity){ + printf("gc_job_manager: warning: affinity request was ignored\n"); + } + + if (d_options.gang_schedule){ + d_gang = spe_gang_context_sptr(spe_gang_context_create(0), gang_deleter()); + if (!d_gang){ + perror("gc_job_manager_impl[spe_gang_context_create]"); + throw std::runtime_error("spe_gang_context_create"); + } + } + + // ---------------------------------------------------------------- + // initalize the job queue + + d_queue = (gc_jd_queue_t *) aligned_alloc(sizeof(gc_jd_queue_t)); + _d_queue_boost = + boost::shared_ptr<void>((void *) d_queue, free_deleter()); + gc_jd_queue_init(d_queue); + + + // ---------------------------------------------------------------- + // create the spe contexts + + // 1 spu_arg struct for each SPE + assert(sizeof(gc_spu_args_t) % 16 == 0); + d_spu_args = + (gc_spu_args_t *) aligned_alloc(MAX_SPES * sizeof(gc_spu_args_t), 16); + _d_spu_args_boost = + boost::shared_ptr<void>((void *) d_spu_args, free_deleter()); + + // 2 completion info structs for each SPE (we double buffer them) + assert(sizeof(gc_comp_info_t) % CACHE_LINE_SIZE == 0); + d_comp_info = + (gc_comp_info_t *) aligned_alloc(2 * MAX_SPES * sizeof(gc_comp_info_t), + CACHE_LINE_SIZE); + _d_comp_info_boost = + boost::shared_ptr<void>((void *) d_comp_info, free_deleter()); + + + // get a handle to the spe program + + spe_program_handle_t *spe_image = d_options.program_handle; + + // fish proc_def table out of SPE ELF file + + if (!gcpd_find_table(spe_image, &d_proc_def, &d_nproc_defs, &d_proc_def_ls_addr)){ + fprintf(stderr, "gc_job_manager_impl: couldn't find gc_proc_defs in SPE ELF file.\n"); + throw std::runtime_error("no gc_proc_defs"); + } + // fprintf(stderr, "d_proc_def_ls_addr = 0x%0x\n", d_proc_def_ls_addr); + + int spe_flags = (SPE_EVENTS_ENABLE + | SPE_CFG_SIGNOTIFY1_OR + | SPE_CFG_SIGNOTIFY2_OR); + + for (unsigned int i = 0; i < d_options.nspes; i++){ + // FIXME affinity stuff goes here + d_worker[i].spe_ctx = spe_context_create(spe_flags, d_gang.get());; + if (d_worker[i].spe_ctx == 0){ + perror("spe_context_create"); + throw std::runtime_error("spe_context_create"); + } + d_worker[i].spe_idx = i; + d_worker[i].spu_args = &d_spu_args[i]; + d_worker[i].spu_args->queue = ptr_to_ea(d_queue); + d_worker[i].spu_args->comp_info[0] = ptr_to_ea(&d_comp_info[2*i+0]); + d_worker[i].spu_args->comp_info[1] = ptr_to_ea(&d_comp_info[2*i+1]); + d_worker[i].spu_args->spu_idx = i; + d_worker[i].spu_args->nspus = d_options.nspes; + d_worker[i].spu_args->proc_def_ls_addr = d_proc_def_ls_addr; + d_worker[i].spu_args->nproc_defs = d_nproc_defs; + d_worker[i].spu_args->log.base = 0; + d_worker[i].spu_args->log.nentries = 0; + d_worker[i].state = WS_INIT; + + int r = spe_program_load(d_worker[i].spe_ctx, spe_image); + if (r != 0){ + perror("spe_program_load"); + throw std::runtime_error("spe_program_load"); + } + } + + setup_logfiles(); + + // ---------------------------------------------------------------- + // initalize the free list of job descriptors + + d_free_list = (gc_jd_stack_t *) aligned_alloc(sizeof(gc_jd_stack_t)); + // This ensures that the memory associated with d_free_list is + // automatically freed in the destructor or if an exception occurs + // here in the constructor. + _d_free_list_boost = + boost::shared_ptr<void>((void *) d_free_list, free_deleter()); + gc_jd_stack_init(d_free_list); + + if (debug()){ + printf("sizeof(d_jd[0]) = %d (0x%x)\n", sizeof(d_jd[0]), sizeof(d_jd[0])); + printf("max_jobs = %u\n", d_options.max_jobs); + } + + // Initialize the array of job descriptors. + d_jd = (gc_job_desc_t *) aligned_alloc(sizeof(d_jd[0]) * d_options.max_jobs); + _d_jd_boost = boost::shared_ptr<void>((void *) d_jd, free_deleter()); + + + // set unique job_id + for (int i = 0; i < (int) d_options.max_jobs; i++) + d_jd[i].sys.job_id = i; + + // push them onto the free list + for (int i = d_options.max_jobs - 1; i >= 0; i--) + free_job_desc(&d_jd[i]); + + // ---------------------------------------------------------------- + // initialize d_client_thread + + { + gc_client_thread_info_sa cti( + new gc_client_thread_info[d_options.max_client_threads]); + + d_client_thread.swap(cti); + + for (unsigned int i = 0; i < d_options.max_client_threads; i++) + d_client_thread[i].d_client_id = i; + } + + // ---------------------------------------------------------------- + // initialize bitvectors + + // initialize d_bvlen, the number of longs in job related bitvectors. + int bits_per_long = sizeof(unsigned long) * 8; + d_bvlen = (d_options.max_jobs + bits_per_long - 1) / bits_per_long; + + // allocate all bitvectors in a single cache-aligned chunk + size_t nlongs = d_bvlen * d_options.max_client_threads; + void *p = aligned_alloc(nlongs * sizeof(unsigned long)); + _d_all_bitvectors = boost::shared_ptr<void>(p, free_deleter()); + + // Now point the gc_client_thread_info bitvectors into this storage + unsigned long *v = (unsigned long *) p; + + for (unsigned int i = 0; i < d_options.max_client_threads; i++, v += d_bvlen) + d_client_thread[i].d_jobs_done = v; + + + // ---------------------------------------------------------------- + // create the spe event handler & worker (SPE) threads + + create_event_handler(); + +} + +//////////////////////////////////////////////////////////////////////// + +gc_job_manager_impl::~gc_job_manager_impl() +{ + shutdown(); + + d_jd = 0; // handled via _d_jd_boost + d_free_list = 0; // handled via _d_free_list_boost + d_queue = 0; // handled via _d_queue_boost + + // clear cti, since we've deleted the underlying data + pthread_setspecific(s_client_key, 0); + + unmap_logfiles(); +} + +bool +gc_job_manager_impl::shutdown() +{ + omni_mutex_lock l(d_eh_mutex); + + d_shutdown_requested = true; // set flag for event handler thread + + // should only happens during early QA code + if (d_eh_thread == 0 && d_eh_state == EHS_INIT) + return false; + + while (d_eh_state != EHS_DEAD) // wait for it to finish + d_eh_cond.wait(); + + return true; +} + +int +gc_job_manager_impl::nspes() const +{ + return d_options.nspes; +} + +//////////////////////////////////////////////////////////////////////// + +void +gc_job_manager_impl::bv_zero(unsigned long *bv) +{ + memset(bv, 0, sizeof(unsigned long) * d_bvlen); +} + +inline void +gc_job_manager_impl::bv_clr(unsigned long *bv, unsigned int bitno) +{ + unsigned int wi = bitno / (sizeof (unsigned long) * 8); + unsigned int bi = bitno & ((sizeof (unsigned long) * 8) - 1); + bv[wi] &= ~(1UL << bi); +} + +inline void +gc_job_manager_impl::bv_set(unsigned long *bv, unsigned int bitno) +{ + unsigned int wi = bitno / (sizeof (unsigned long) * 8); + unsigned int bi = bitno & ((sizeof (unsigned long) * 8) - 1); + bv[wi] |= (1UL << bi); +} + +inline bool +gc_job_manager_impl::bv_isset(unsigned long *bv, unsigned int bitno) +{ + unsigned int wi = bitno / (sizeof (unsigned long) * 8); + unsigned int bi = bitno & ((sizeof (unsigned long) * 8) - 1); + return (bv[wi] & (1UL << bi)) != 0; +} + +inline bool +gc_job_manager_impl::bv_isclr(unsigned long *bv, unsigned int bitno) +{ + unsigned int wi = bitno / (sizeof (unsigned long) * 8); + unsigned int bi = bitno & ((sizeof (unsigned long) * 8) - 1); + return (bv[wi] & (1UL << bi)) == 0; +} + +//////////////////////////////////////////////////////////////////////// + +gc_job_desc * +gc_job_manager_impl::alloc_job_desc() +{ + // stack is lock free, thus safe to call from any thread + return gc_jd_stack_pop(d_free_list); +} + +void +gc_job_manager_impl::free_job_desc(gc_job_desc *jd) +{ + // stack is lock free, thus safe to call from any thread + if (jd != 0) + gc_jd_stack_push(d_free_list, jd); +} + +//////////////////////////////////////////////////////////////////////// + +/* + * We check as much as we can here on the PPE side, so that the SPE + * doesn't have to. + */ +static bool +check_direct_args(gc_job_desc *jd, gc_job_direct_args *args) +{ + if (args->nargs > MAX_ARGS_DIRECT){ + jd->status = JS_BAD_N_DIRECT; + return false; + } + + return true; +} + +static bool +check_ea_args(gc_job_desc *jd, gc_job_ea_args *p) +{ + if (p->nargs > MAX_ARGS_EA){ + jd->status = JS_BAD_N_EA; + return false; + } + + uint32_t dir_union = 0; + + for (unsigned int i = 0; i < p->nargs; i++){ + dir_union |= p->arg[i].direction; + switch(p->arg[i].direction){ + case GCJD_DMA_GET: + case GCJD_DMA_PUT: + break; + + default: + jd->status = JS_BAD_DIRECTION; + return false; + } + } + + if (p->nargs > 1){ + unsigned int common_eah = (p->arg[0].ea_addr) >> 32; + for (unsigned int i = 1; i < p->nargs; i++){ + if ((p->arg[i].ea_addr >> 32) != common_eah){ + jd->status = JS_BAD_EAH; + return false; + } + } + } + + jd->sys.direction_union = dir_union; + return true; +} + +bool +gc_job_manager_impl::submit_job(gc_job_desc *jd) +{ + if (unlikely(d_shutdown_requested)){ + jd->status = JS_SHUTTING_DOWN; + return false; + } + + // Ensure it's one of our job descriptors + + if (jd < d_jd || jd >= &d_jd[d_options.max_jobs]){ + jd->status = JS_BAD_JOB_DESC; + return false; + } + + // Ensure we've got a client_thread_info assigned to this thread. + + gc_client_thread_info *cti = + (gc_client_thread_info *) pthread_getspecific(s_client_key); + if (unlikely(cti == 0)){ + if ((cti = alloc_cti()) == 0){ + fprintf(stderr, "gc_job_manager_impl::submit_job: Too many client threads.\n"); + jd->status = JS_TOO_MANY_CLIENTS; + return false; + } + int r = pthread_setspecific(s_client_key, cti); + if (r != 0){ + jd->status = JS_BAD_JUJU; + fprintf(stderr, "pthread_setspecific failed (return = %d)\n", r); + return false; + } + } + + if (jd->proc_id == GCP_UNKNOWN_PROC){ + jd->status = JS_UNKNOWN_PROC; + return false; + } + + if (!check_direct_args(jd, &jd->input)) + return false; + + if (!check_direct_args(jd, &jd->output)) + return false; + + if (!check_ea_args(jd, &jd->eaa)) + return false; + + jd->status = JS_OK; + jd->sys.client_id = cti->d_client_id; + + // FIXME keep count of jobs in progress? + + gc_jd_queue_enqueue(d_queue, jd); + return true; +} + +bool +gc_job_manager_impl::wait_job(gc_job_desc *jd) +{ + bool done; + return wait_jobs(1, &jd, &done, GC_WAIT_ANY) == 1; +} + +int +gc_job_manager_impl::wait_jobs(unsigned int njobs, + gc_job_desc *jd[], + bool done[], + gc_wait_mode mode) +{ + unsigned int i; + + gc_client_thread_info *cti = + (gc_client_thread_info *) pthread_getspecific(s_client_key); + if (unlikely(cti == 0)) + return -1; + + for (i = 0; i < njobs; i++){ + done[i] = false; + if (unlikely(jd[i]->sys.client_id != cti->d_client_id)){ + fprintf(stderr, "gc_job_manager_impl::wait_jobs: can't wait for a job you didn't submit\n"); + return -1; + } + } + + { + omni_mutex_lock l(cti->d_mutex); + + // setup info for event handler + cti->d_state = (mode == GC_WAIT_ANY) ? CT_WAIT_ANY : CT_WAIT_ALL; + cti->d_njobs_waiting_for = njobs; + cti->d_jobs_waiting_for = jd; + assert(cti->d_jobs_done != 0); + + unsigned int ndone = 0; + + // wait for jobs to complete + + while (1){ + ndone = 0; + for (i= 0; i < njobs; i++){ + if (done[i]) + ndone++; + else if (bv_isset(cti->d_jobs_done, jd[i]->sys.job_id)){ + bv_clr(cti->d_jobs_done, jd[i]->sys.job_id); + done[i] = true; + ndone++; + } + } + + if (mode == GC_WAIT_ANY && ndone > 0) + break; + + if (mode == GC_WAIT_ALL && ndone == njobs) + break; + + // FIXME what happens when somebody calls shutdown? + + cti->d_cond.wait(); // wait for event handler to wake us up + } + + cti->d_state = CT_NOT_WAITING; + cti->d_njobs_waiting_for = 0; // tidy up (not reqd) + cti->d_jobs_waiting_for = 0; // tidy up (not reqd) + return ndone; + } +} + +//////////////////////////////////////////////////////////////////////// + +bool +gc_job_manager_impl::send_all_spes(uint32_t msg) +{ + bool ok = true; + + for (unsigned int i = 0; i < d_options.nspes; i++) + ok &= send_spe(i, msg); + + return ok; +} + +bool +gc_job_manager_impl::send_spe(unsigned int spe, uint32_t msg) +{ + if (spe >= d_options.nspes) + return false; + + int r = spe_in_mbox_write(d_worker[spe].spe_ctx, &msg, 1, + SPE_MBOX_ALL_BLOCKING); + if (r < 0){ + perror("spe_in_mbox_write"); + return false; + } + + return r == 1; +} + +//////////////////////////////////////////////////////////////////////// + +static void +pthread_create_failure_msg(int r, const char *which) +{ + char buf[256]; + char *s = 0; + + switch (r){ + case EAGAIN: s = "EAGAIN"; break; + case EINVAL: s = "EINVAL"; break; + case EPERM: s = "EPERM"; break; + default: + snprintf(buf, sizeof(buf), "Unknown error %d", r); + s = buf; + break; + } + fprintf(stderr, "pthread_create[%s] failed: %s\n", which, s); +} + + +static bool +start_thread(pthread_t *thread, + void *(*start_routine)(void *), void *arg, + const char *msg) +{ + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + // FIXME save sigprocmask + // FIXME set sigprocmask + + int r = pthread_create(thread, &attr, start_routine, arg); + + // FIXME restore sigprocmask + + if (r != 0){ + pthread_create_failure_msg(r, msg); + return false; + } + return true; +} + + +//////////////////////////////////////////////////////////////////////// + +static void *start_worker(void *arg); + +static void * +start_event_handler(void *arg) +{ + gc_job_manager_impl *p = (gc_job_manager_impl *) arg; + p->event_handler_loop(); + return 0; +} + +void +gc_job_manager_impl::create_event_handler() +{ + // create the SPE event handler and register our interest in events + + d_spe_event_handler.ptr = spe_event_handler_create(); + if (d_spe_event_handler.ptr == 0){ + perror("spe_event_handler_create"); + throw std::runtime_error("spe_event_handler_create"); + } + + for (unsigned int i = 0; i < d_options.nspes; i++){ + spe_event_unit_t eu; + memset(&eu, 0, sizeof(eu)); + eu.events = SPE_EVENT_OUT_INTR_MBOX | SPE_EVENT_SPE_STOPPED; + eu.spe = d_worker[i].spe_ctx; + eu.data.u32 = i; // set in events returned by spe_event_wait + + if (spe_event_handler_register(d_spe_event_handler.ptr, &eu) != 0){ + perror("spe_event_handler_register"); + throw std::runtime_error("spe_event_handler_register"); + } + } + + // create our event handling thread + + if (!start_thread(&d_eh_thread, start_event_handler, this, "event_handler")){ + throw std::runtime_error("pthread_create"); + } + + // create the SPE worker threads + + bool ok = true; + for (unsigned int i = 0; ok && i < d_options.nspes; i++){ + char name[256]; + snprintf(name, sizeof(name), "worker[%d]", i); + ok &= start_thread(&d_worker[i].thread, start_worker, + &d_worker[i], name); + } + + if (!ok){ + // + // FIXME Clean up the mess. Need to terminate event handler and all workers. + // + // this should cause the workers to exit, unless they're seriously broken + send_all_spes(MK_MBOX_MSG(OP_EXIT, 0)); + + shutdown(); + + throw std::runtime_error("pthread_create"); + } +} + +//////////////////////////////////////////////////////////////////////// + +void +gc_job_manager_impl::set_eh_state(evt_handler_state s) +{ + omni_mutex_lock l(d_eh_mutex); + d_eh_state = s; + d_eh_cond.broadcast(); +} + +void +gc_job_manager_impl::set_ea_args_maxsize(int maxsize) +{ + omni_mutex_lock l(d_eh_mutex); + d_ea_args_maxsize = maxsize; + d_eh_cond.broadcast(); +} + +void +gc_job_manager_impl::print_event(spe_event_unit_t *evt) +{ + printf("evt: spe = %d events = (0x%x)", evt->data.u32, evt->events); + + if (evt->events & SPE_EVENT_OUT_INTR_MBOX) + printf(" OUT_INTR_MBOX"); + + if (evt->events & SPE_EVENT_IN_MBOX) + printf(" IN_MBOX"); + + if (evt->events & SPE_EVENT_TAG_GROUP) + printf(" TAG_GROUP"); + + if (evt->events & SPE_EVENT_SPE_STOPPED) + printf(" SPE_STOPPED"); + + printf("\n"); +} + +struct job_client_info { + uint16_t job_id; + uint16_t client_id; +}; + +static int +compare_jci_clients(const void *va, const void *vb) +{ + const job_client_info *a = (job_client_info *) va; + const job_client_info *b = (job_client_info *) vb; + + return a->client_id - b->client_id; +} + +void +gc_job_manager_impl::notify_clients_jobs_are_done(unsigned int spe_num, + unsigned int completion_info_idx) +{ + const char *msg = "gc_job_manager_impl::notify_client_job_is_done (INTERNAL ERROR)"; + + smp_rmb(); // order reads so we know that data sent from SPE is here + + gc_comp_info_t *ci = &d_comp_info[2 * spe_num + (completion_info_idx & 0x1)]; + + if (ci->ncomplete == 0){ // never happens, but ensures code below is correct + ci->in_use = 0; + return; + } + + if (0){ + static int total_jobs; + static int total_msgs; + total_msgs++; + total_jobs += ci->ncomplete; + printf("ppe: tj = %6d tm = %6d\n", total_jobs, total_msgs); + } + + job_client_info gci[GC_CI_NJOBS]; + + /* + * Make one pass through and sanity check everything while filling in gci + */ + for (unsigned int i = 0; i < ci->ncomplete; i++){ + unsigned int job_id = ci->job_id[i]; + + if (job_id >= d_options.max_jobs){ + // internal error, shouldn't happen + fprintf(stderr,"%s: invalid job_id = %d\n", msg, job_id); + ci->in_use = 0; // clear flag so SPE knows we're done with it + return; + } + gc_job_desc *jd = &d_jd[job_id]; + + if (jd->sys.client_id >= d_options.max_client_threads){ + // internal error, shouldn't happen + fprintf(stderr, "%s: invalid client_id = %d\n", msg, jd->sys.client_id); + ci->in_use = 0; // clear flag so SPE knows we're done with it + return; + } + + gci[i].job_id = job_id; + gci[i].client_id = jd->sys.client_id; + } + + // sort by client_id so we only have to lock & signal once / client + + if (ci->ncomplete > 1) + qsort(gci, ci->ncomplete, sizeof(gci[0]), compare_jci_clients); + + // "wind-in" + + gc_client_thread_info *last_cti = &d_client_thread[gci[0].client_id]; + last_cti->d_mutex.lock(); + bv_set(last_cti->d_jobs_done, gci[0].job_id); // mark job done + + for (unsigned int i = 1; i < ci->ncomplete; i++){ + + gc_client_thread_info *cti = &d_client_thread[gci[i].client_id]; + + if (cti != last_cti){ // new client? + + // yes. signal old client, unlock old, lock new + + // FIXME we could distinguish between CT_WAIT_ALL & CT_WAIT_ANY + + if (last_cti->d_state == CT_WAIT_ANY || last_cti->d_state == CT_WAIT_ALL) + last_cti->d_cond.signal(); // wake client thread up + + last_cti->d_mutex.unlock(); + cti->d_mutex.lock(); + last_cti = cti; + } + + // mark job done + bv_set(cti->d_jobs_done, gci[i].job_id); + } + + // "wind-out" + + if (last_cti->d_state == CT_WAIT_ANY || last_cti->d_state == CT_WAIT_ALL) + last_cti->d_cond.signal(); // wake client thread up + last_cti->d_mutex.unlock(); + + ci->in_use = 0; // clear flag so SPE knows we're done with it +} + +void +gc_job_manager_impl::handle_event(spe_event_unit_t *evt) +{ + // print_event(evt); + + int spe_num = evt->data.u32; + + // only a single event type can be signaled at a time + + if (evt->events == SPE_EVENT_OUT_INTR_MBOX) { // SPE sent us 1 or more msgs + static const int NMSGS = 32; + unsigned int msg[NMSGS]; + int n = spe_out_intr_mbox_read(evt->spe, msg, NMSGS, SPE_MBOX_ANY_BLOCKING); + // printf("spe_out_intr_mbox_read = %d\n", n); + if (n < 0){ + perror("spe_out_intr_mbox_read"); + } + else { + for (int i = 0; i < n; i++){ + switch(MBOX_MSG_OP(msg[i])){ + case OP_JOBS_DONE: + if (debug()) + printf("eh: job_done (0x%08x) from spu[%d]\n", msg[i], spe_num); + notify_clients_jobs_are_done(spe_num, MBOX_MSG_ARG(msg[i])); + break; + + case OP_SPU_BUFSIZE: + set_ea_args_maxsize(MBOX_MSG_ARG(msg[i])); + break; + + case OP_EXIT: + default: + printf("eh: Unexpected msg (0x%08x) from spu[%d]\n", msg[i], spe_num); + break; + } + } + } + } + else if (evt->events == SPE_EVENT_SPE_STOPPED){ // the SPE stopped + spe_stop_info_t si; + int r = spe_stop_info_read(evt->spe, &si); + if (r < 0){ + perror("spe_stop_info_read"); + } + else { + switch (si.stop_reason){ + case SPE_EXIT: + if (debug()){ + printf("eh: spu[%d] SPE_EXIT w/ exit_code = %d\n", + spe_num, si.result.spe_exit_code); + } + break; + case SPE_STOP_AND_SIGNAL: + printf("eh: spu[%d] SPE_STOP_AND_SIGNAL w/ spe_signal_code = 0x%x\n", + spe_num, si.result.spe_signal_code); + break; + case SPE_RUNTIME_ERROR: + printf("eh: spu[%d] SPE_RUNTIME_ERROR w/ spe_runtime_error = 0x%x\n", + spe_num, si.result.spe_runtime_error); + break; + case SPE_RUNTIME_EXCEPTION: + printf("eh: spu[%d] SPE_RUNTIME_EXCEPTION w/ spe_runtime_exception = 0x%x\n", + spe_num, si.result.spe_runtime_exception); + break; + case SPE_RUNTIME_FATAL: + printf("eh: spu[%d] SPE_RUNTIME_FATAL w/ spe_runtime_fatal = 0x%x\n", + spe_num, si.result.spe_runtime_fatal); + break; + case SPE_CALLBACK_ERROR: + printf("eh: spu[%d] SPE_CALLBACK_ERROR w/ spe_callback_error = 0x%x\n", + spe_num, si.result.spe_callback_error); + break; + case SPE_ISOLATION_ERROR: + printf("eh: spu[%d] SPE_ISOLATION_ERROR w/ spe_isolation_error = 0x%x\n", + spe_num, si.result.spe_isolation_error); + break; + default: + printf("eh: spu[%d] UNKNOWN STOP REASON (%d) w/ spu_status = 0x%x\n", + spe_num, si.stop_reason, si.spu_status); + break; + } + } + } +#if 0 // not enabled + else if (evt->events == SPE_EVENT_IN_MBOX){ // there's room to write to SPE + // spe_in_mbox_write (ignore) + } + else if (evt->events == SPE_EVENT_TAG_GROUP){ // our DMA completed + // spe_mfcio_tag_status_read + } +#endif + else { + fprintf(stderr, "handle_event: unexpected evt->events = 0x%x\n", evt->events); + return; + } +} + +// +// This is the "main program" of the event handling thread +// +void +gc_job_manager_impl::event_handler_loop() +{ + static const int MAX_EVENTS = 16; + static const int TIMEOUT = 20; // how long to block in milliseconds + + spe_event_unit_t events[MAX_EVENTS]; + + if (d_debug) + printf("event_handler_loop: starting\n"); + + set_eh_state(EHS_RUNNING); + + // ask the first spe for its max bufsize + send_spe(0, MK_MBOX_MSG(OP_GET_SPU_BUFSIZE, 0)); + + while (1){ + switch(d_eh_state){ + + case EHS_RUNNING: // normal stuff + if (d_shutdown_requested) { + set_eh_state(EHS_SHUTTING_DOWN); + } + break; + + case EHS_SHUTTING_DOWN: + + // FIXME wait until job queue is empty, then tell them to exit + + send_all_spes(MK_MBOX_MSG(OP_EXIT, 0)); + set_eh_state(EHS_WAITING_FOR_WORKERS_TO_DIE); + break; + + case EHS_WAITING_FOR_WORKERS_TO_DIE: + { + bool all_dead = true; + for (unsigned int i = 0; i < d_options.nspes; i++) + all_dead &= d_worker[i].state == WS_DEAD; + + if (all_dead){ + set_eh_state(EHS_DEAD); + if (d_debug) + printf("event_handler_loop: exiting\n"); + return; + } + } + break; + + default: + set_eh_state(EHS_DEAD); + printf("event_handler_loop(default): exiting\n"); + return; + } + + // block waiting for events... + int nevents = spe_event_wait(d_spe_event_handler.ptr, + events, MAX_EVENTS, TIMEOUT); + if (nevents < 0){ + perror("spe_wait_event"); + // FIXME bail? + } + for (int i = 0; i < nevents; i++){ + handle_event(&events[i]); + } + } +} + +//////////////////////////////////////////////////////////////////////// +// This is the top of the SPE worker threads + +static void * +start_worker(void *arg) +{ + worker_ctx *w = (worker_ctx *) arg; + spe_stop_info_t si; + + w->state = WS_RUNNING; + if (s_worker_debug) + printf("worker[%d]: WS_RUNNING\n", w->spe_idx); + + unsigned int entry = SPE_DEFAULT_ENTRY; + int r = spe_context_run(w->spe_ctx, &entry, 0, w->spu_args, 0, &si); + + if (r < 0){ // error + char buf[64]; + snprintf(buf, sizeof(buf), "worker[%d]: spe_context_run", w->spe_idx); + perror(buf); + } + else if (r == 0){ + // spe program called exit. + if (s_worker_debug) + printf("worker[%d]: SPE_EXIT w/ exit_code = %d\n", + w->spe_idx, si.result.spe_exit_code); + } + else { + // called stop_and_signal + // + // I'm not sure we'll ever get here. I think the event + // handler will catch this... + printf("worker[%d]: SPE_STOP_AND_SIGNAL w/ spe_signal_code = 0x%x\n", + w->spe_idx, si.result.spe_signal_code); + } + + // in any event, we're committing suicide now ;) + if (s_worker_debug) + printf("worker[%d]: WS_DEAD\n", w->spe_idx); + + w->state = WS_DEAD; + return 0; +} + +//////////////////////////////////////////////////////////////////////// + +gc_client_thread_info * +gc_job_manager_impl::alloc_cti() +{ + for (unsigned int i = 0; i < d_options.max_client_threads; i++){ + if (d_client_thread[i].d_free){ + // try to atomically grab it + if (_atomic_dec_if_positive(ptr_to_ea(&d_client_thread[i].d_free)) == 0){ + // got it... + gc_client_thread_info *cti = &d_client_thread[i]; + cti->d_state = CT_NOT_WAITING; + bv_zero(cti->d_jobs_done); + cti->d_njobs_waiting_for = 0; + cti->d_jobs_waiting_for = 0; + + return cti; + } + } + } + return 0; +} + +void +gc_job_manager_impl::free_cti(gc_client_thread_info *cti) +{ + assert((size_t) (cti - d_client_thread.get()) < d_options.max_client_threads); + cti->d_free = 1; +} + +int +gc_job_manager_impl::ea_args_maxsize() +{ + omni_mutex_lock l(d_eh_mutex); + + while (d_ea_args_maxsize == 0) // wait for it to be initialized + d_eh_cond.wait(); + + return d_ea_args_maxsize; +} + +void +gc_job_manager_impl::set_debug(int debug) +{ + d_debug = debug; + s_worker_debug = debug; +} + +int +gc_job_manager_impl::debug() +{ + return d_debug; +} + +//////////////////////////////////////////////////////////////////////// + +void +gc_job_manager_impl::setup_logfiles() +{ + if (!d_options.enable_logging) + return; + + if (d_options.log2_nlog_entries == 0) + d_options.log2_nlog_entries = 12; + + // must end up a multiple of the page size + + size_t pagesize = getpagesize(); + size_t s = (1 << d_options.log2_nlog_entries) * sizeof(gc_log_entry_t); + s = ((s + pagesize - 1) / pagesize) * pagesize; + size_t nentries = s / sizeof(gc_log_entry_t); + assert(is_power_of_2(nentries)); + + for (unsigned int i = 0; i < d_options.nspes; i++){ + char filename[100]; + snprintf(filename, sizeof(filename), "spu_log.%02d", i); + int fd = open(filename, O_CREAT|O_TRUNC|O_RDWR, 0664); + if (fd == -1){ + perror(filename); + return; + } + lseek(fd, s - 1, SEEK_SET); + write(fd, "\0", 1); + void *p = mmap(0, s, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + if (p == MAP_FAILED){ + perror("gc_job_manager_impl::setup_logfiles: mmap"); + close(fd); + return; + } + close(fd); + memset(p, 0, s); + d_spu_args[i].log.base = ptr_to_ea(p); + d_spu_args[i].log.nentries = nentries; + } +} + +void +gc_job_manager_impl::sync_logfiles() +{ + for (unsigned int i = 0; i < d_options.nspes; i++){ + if (d_spu_args[i].log.base) + msync(ea_to_ptr(d_spu_args[i].log.base), + d_spu_args[i].log.nentries * sizeof(gc_log_entry_t), + MS_ASYNC); + } +} + +void +gc_job_manager_impl::unmap_logfiles() +{ + for (unsigned int i = 0; i < d_options.nspes; i++){ + if (d_spu_args[i].log.base) + munmap(ea_to_ptr(d_spu_args[i].log.base), + d_spu_args[i].log.nentries * sizeof(gc_log_entry_t)); + } +} + +//////////////////////////////////////////////////////////////////////// +// +// lookup proc names in d_proc_def table + +gc_proc_id_t +gc_job_manager_impl::lookup_proc(const std::string &proc_name) +{ + for (int i = 0; i < d_nproc_defs; i++) + if (proc_name == d_proc_def[i].name) + return i; + + return GCP_UNKNOWN_PROC; +} + +std::vector<std::string> +gc_job_manager_impl::proc_names() +{ + std::vector<std::string> r; + for (int i = 0; i < d_nproc_defs; i++) + r.push_back(d_proc_def[i].name); + + return r; +} + +//////////////////////////////////////////////////////////////////////// + +worker_ctx::~worker_ctx() +{ + if (spe_ctx){ + int r = spe_context_destroy(spe_ctx); + if (r != 0){ + perror("spe_context_destroy"); + } + spe_ctx = 0; + } + state = WS_FREE; +} diff --git a/gcell/src/lib/runtime/gc_job_manager_impl.h b/gcell/src/lib/runtime/gc_job_manager_impl.h new file mode 100644 index 000000000..46897848c --- /dev/null +++ b/gcell/src/lib/runtime/gc_job_manager_impl.h @@ -0,0 +1,253 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef INCLUDED_GC_JOB_MANAGER_IMPL_H +#define INCLUDED_GC_JOB_MANAGER_IMPL_H + +#include "gc_job_manager.h" +#include "gc_client_thread_info.h" +#include "gc_jd_stack.h" +#include "gc_jd_queue.h" +#include "gc_spu_args.h" +#include <libspe2.h> +#include <vector> +#include <boost/shared_ptr.hpp> +#include <boost/scoped_array.hpp> + +typedef boost::shared_ptr<spe_gang_context> spe_gang_context_sptr; +typedef boost::shared_ptr<spe_program_handle_t> spe_program_handle_sptr; +typedef boost::scoped_array<gc_client_thread_info> gc_client_thread_info_sa; + + +enum worker_state { + WS_FREE, // not in use + WS_INIT, // allocated and being initialized + WS_RUNNING, // the thread is running + WS_DEAD, // the thread is dead +}; + +struct worker_ctx { + volatile worker_state state; + unsigned int spe_idx; // [0, nspes-1] + spe_context_ptr_t spe_ctx; + pthread_t thread; + gc_spu_args_t *spu_args; // pointer to 16-byte aligned struct + + worker_ctx() + : state(WS_FREE), spe_idx(0), spe_ctx(0), + thread(0), spu_args(0) {} + ~worker_ctx(); +}; + +enum evt_handler_state { + EHS_INIT, // being initialized + EHS_RUNNING, // thread is running + EHS_SHUTTING_DOWN, // in process of shutting down everything + EHS_WAITING_FOR_WORKERS_TO_DIE, + EHS_DEAD, // thread is dead +}; + +struct spe_event_handler { + spe_event_handler_ptr_t ptr; + + spe_event_handler() : ptr(0) {} + ~spe_event_handler(){ + if (ptr){ + if (spe_event_handler_destroy(ptr) != 0){ + perror("spe_event_handler_destroy"); + } + } + } +}; + + +/*! + * \brief Concrete class that manages SPE jobs. + * + * This class contains all the implementation details. + */ +class gc_job_manager_impl : public gc_job_manager +{ + enum { MAX_SPES = 16 }; + + int d_debug; + gc_jm_options d_options; + spe_program_handle_sptr d_spe_image; + spe_gang_context_sptr d_gang; // boost::shared_ptr + + worker_ctx d_worker[MAX_SPES]; // SPE ctx, thread, etc + gc_spu_args_t *d_spu_args; // 16-byte aligned structs + boost::shared_ptr<void> _d_spu_args_boost; // hack for automatic storage mgmt + + gc_comp_info_t *d_comp_info; // 128-byte aligned structs + boost::shared_ptr<void> _d_comp_info_boost; // hack for automatic storage mgmt + + // used to coordinate communication w/ the event handling thread + omni_mutex d_eh_mutex; + omni_condition d_eh_cond; + pthread_t d_eh_thread; // the event handler thread + volatile evt_handler_state d_eh_state; + volatile bool d_shutdown_requested; + spe_event_handler d_spe_event_handler; + + + // All of the job descriptors are hung off of here. + // We allocate them all in a single cache aligned chunk. + gc_job_desc_t *d_jd; // [options.max_jobs] + boost::shared_ptr<void> _d_jd_boost; // hack for automatic storage mgmt + + gc_client_thread_info_sa d_client_thread; // [options.max_client_threads] + + // We use bitvectors to represent the completing state of a job. Each + // bitvector is d_bvlen longs in length. + int d_bvlen; // bit vector length in longs + + // This contains the storage for all the bitvectors used by the job + // manager. There's 1 for each client thread, in the d_jobs_done + // field. We allocate them all in a single cache aligned chunk. + boost::shared_ptr<void> _d_all_bitvectors; // hack for automatic storage mgmt + + // Lock free stack where we keep track of the free job descriptors. + gc_jd_stack_t *d_free_list; // stack of free job descriptors + boost::shared_ptr<void> _d_free_list_boost; // hack for automatic storage mgmt + + // The PPE inserts jobs here; SPEs pull jobs from here. + gc_jd_queue_t *d_queue; // job queue + boost::shared_ptr<void> _d_queue_boost; // hack for automatic storage mgmt + + int d_ea_args_maxsize; + + struct gc_proc_def *d_proc_def; // the SPE procedure table + uint32_t d_proc_def_ls_addr; // the LS address of the table + int d_nproc_defs; // number of proc_defs in table + + gc_client_thread_info *alloc_cti(); + void free_cti(gc_client_thread_info *cti); + + void create_event_handler(); + void set_eh_state(evt_handler_state s); + void set_ea_args_maxsize(int maxsize); + + void notify_clients_jobs_are_done(unsigned int spe_num, + unsigned int completion_info_idx); + +public: + void event_handler_loop(); // really private + +private: + bool send_all_spes(uint32_t msg); + bool send_spe(unsigned int spe, uint32_t msg); + void print_event(spe_event_unit_t *evt); + void handle_event(spe_event_unit_t *evt); + + // bitvector ops + void bv_zero(unsigned long *bv); + void bv_clr(unsigned long *bv, unsigned int bitno); + void bv_set(unsigned long *bv, unsigned int bitno); + bool bv_isset(unsigned long *bv, unsigned int bitno); + bool bv_isclr(unsigned long *bv, unsigned int bitno); + + void setup_logfiles(); + void sync_logfiles(); + void unmap_logfiles(); + + friend gc_job_manager *gc_make_job_manager(const gc_jm_options *options); + + gc_job_manager_impl(const gc_jm_options *options = 0); + +public: + virtual ~gc_job_manager_impl(); + + /*! + * Stop accepting new jobs. Wait for existing jobs to complete. + * Return all managed SPE's to the system. + */ + virtual bool shutdown(); + + /*! + * \brief Return number of SPE's currently allocated to job manager. + */ + virtual int nspes() const; + + /*! + * \brief Return a pointer to a properly aligned job descriptor, + * or zero if none are available. + */ + virtual gc_job_desc *alloc_job_desc(); + + /* + *! Return a job descriptor previously allocated with alloc_job_desc() + * + * \param[in] jd pointer to job descriptor to free. + */ + virtual void free_job_desc(gc_job_desc *jd); + + /*! + * \brief Submit a job for asynchronous processing on an SPE. + * + * \param[in] jd pointer to job description + * + * The caller must not read or write the job description + * or any of the memory associated with any indirect arguments + * until after calling wait_job. + * + * \returns true iff the job was successfully enqueued. + * If submit_job returns false, check jd->status for additional info. + */ + virtual bool submit_job(gc_job_desc *jd); + + /*! + * \brief Wait for job to complete. + * + * A thread may only wait for jobs which it submitted. + * + * \returns true if sucessful, else false. + */ + virtual bool + wait_job(gc_job_desc *jd); + + /*! + * \brief wait for 1 or more jobs to complete. + * + * \param[input] njobs is the length of arrays \p jd and \p done. + * \param[input] jd are the jobs that are to be waited for. + * \param[output] done indicates whether the corresponding job is complete. + * \param[input] mode indicates whether to wait for ALL or ANY of the jobs + * in \p jd to complete. + * + * A thread may only wait for jobs which it submitted. + * + * \returns number of jobs completed, or -1 if error. + */ + virtual int + wait_jobs(unsigned int njobs, + gc_job_desc *jd[], bool done[], gc_wait_mode mode); + + virtual int ea_args_maxsize(); + + virtual gc_proc_id_t lookup_proc(const std::string &name); + virtual std::vector<std::string> proc_names(); + + virtual void set_debug(int debug); + virtual int debug(); +}; + +#endif /* INCLUDED_GC_JOB_MANAGER_IMPL_H */ diff --git a/gcell/src/lib/runtime/gc_proc_def_utils.cc b/gcell/src/lib/runtime/gc_proc_def_utils.cc new file mode 100644 index 000000000..c5b9848fc --- /dev/null +++ b/gcell/src/lib/runtime/gc_proc_def_utils.cc @@ -0,0 +1,123 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gc_proc_def_utils.h> +#include <gc_declare_proc.h> +#include <elf.h> +#include <stdio.h> +#include <string.h> + +static const unsigned char expected[EI_PAD] = { + ELFMAG0, + ELFMAG1, + ELFMAG2, + ELFMAG3, + ELFCLASS32, + ELFDATA2MSB, + EV_CURRENT, + ELFOSABI_SYSV, + 0 +}; + + +/* + * Basically we're going to find the GC_PROC_DEF_SECTION section + * in the ELF file and return a pointer to it. The only things in that + * section are gc_proc_def's + */ +bool +gcpd_find_table(spe_program_handle_t *handle, + struct gc_proc_def **table, int *nentries, uint32_t *ls_addr) +{ + if (!handle || !table || !nentries) + return false; + + *table = 0; + *nentries = 0; + + Elf32_Ehdr *ehdr = (Elf32_Ehdr *)handle->elf_image; + if (!ehdr){ + fprintf(stderr, "gcpd: No ELF image has been loaded\n"); + return false; + } + + // quick check that we're looking at a SPE EXEC object + + if (memcmp(ehdr->e_ident, expected, EI_PAD) != 0){ + fprintf(stderr, "gcpd: invalid ELF header\n"); + return false; + } + + if (ehdr->e_machine != 0x17){ // confirm machine type (EM_SPU) + fprintf(stderr, "gcpd: not an SPE ELF object\n"); + return false; + } + + if (ehdr->e_type != ET_EXEC){ + fprintf(stderr, "gcpd: invalid SPE ELF type.\n"); + fprintf(stderr, "gcpd: SPE type %d != %d\n", ehdr->e_type, ET_EXEC); + return false; + } + + // find the section header table + + Elf32_Shdr *shdr; + Elf32_Shdr *sh; + + if (ehdr->e_shentsize != sizeof (*shdr)){ + fprintf(stderr, "gcpd: invalid section header format.\n"); + return false; + } + + if (ehdr->e_shnum == 0){ + fprintf(stderr, "gcpd: no section headers in file.\n"); + return false; + } + + shdr = (Elf32_Shdr *) ((char *)ehdr + ehdr->e_shoff); + char *str_table = (char *)ehdr + shdr[ehdr->e_shstrndx].sh_offset; + + // traverse the sections looking for GC_PROC_DEF_SECTION + + for (sh = shdr; sh < &shdr[ehdr->e_shnum]; sh++){ + if (0){ + fprintf(stderr, "section name: %s (start: 0x%04x, size: 0x%04x)\n", + str_table + sh->sh_name, sh->sh_offset, sh->sh_size); + } + + if (strcmp(GC_PROC_DEF_SECTION, str_table+sh->sh_name) == 0){ + *table = (struct gc_proc_def *)((char *)ehdr + sh->sh_offset); + if (sh->sh_size % (sizeof(struct gc_proc_def)) != 0){ + fprintf(stderr, "gcpd: %s section has invalid format\n", GC_PROC_DEF_SECTION); + return false; + } + *nentries = sh->sh_size / sizeof(struct gc_proc_def); + *ls_addr = sh->sh_addr; + return true; + } + } + + return false; +} diff --git a/gcell/src/lib/runtime/gc_proc_def_utils.h b/gcell/src/lib/runtime/gc_proc_def_utils.h new file mode 100644 index 000000000..c59e472af --- /dev/null +++ b/gcell/src/lib/runtime/gc_proc_def_utils.h @@ -0,0 +1,42 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_GC_PROC_DEF_UTILS_H +#define INCLUDED_GC_PROC_DEF_UTILS_H + +#include <gc_declare_proc.h> +#include <libspe2.h> + +/*! + * \brief find the gc_proc_def table in the SPE program + * + * \param[in] program is the handle to the loaded SPE program + * \param[out] table points to the table, if it's found + * \param[out] nentries is set to the number of entries in the table. + * \param[out] ls_addr is set to the Local Store address of the table + * + * \returns true if successful, else false + */ +bool +gcpd_find_table(spe_program_handle_t *program, + struct gc_proc_def **table, int *nentries, uint32_t *ls_addr); + + +#endif /* INCLUDED_GC_PROC_DEF_UTILS_H */ diff --git a/gcell/src/lib/runtime/qa_jd_queue.cc b/gcell/src/lib/runtime/qa_jd_queue.cc new file mode 100644 index 000000000..267d4cfb7 --- /dev/null +++ b/gcell/src/lib/runtime/qa_jd_queue.cc @@ -0,0 +1,78 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "qa_jd_queue.h" +#include <cppunit/TestAssert.h> +#include "gc_jd_queue.h" +#include <stdio.h> + + + +static const int NJDS = 16; +static gc_jd_queue_t queue; +static gc_job_desc_t jds[NJDS]; + +// no brainer, single threaded basic checkout +void +qa_jd_queue::t1() +{ + // N.B., queue allocated stuff doesn't obey ((aligned (N))) attributes + //const int NJDS = 8; + //gc_jd_queue_t queue; + //gc_job_desc_t jds[NJDS]; + + //printf("&queue = %p\n", &queue); + //printf("&jds[0] = %p\n", &jds[0]); + //printf("&jds[1] = %p\n", &jds[1]); + + CPPUNIT_ASSERT(((uintptr_t) &queue & 0x7f) == 0); + CPPUNIT_ASSERT(((uintptr_t) &jds[0] & 0x7f) == 0); + CPPUNIT_ASSERT(((uintptr_t) &jds[1] & 0x7f) == 0); + + gc_jd_queue_init(&queue); + + CPPUNIT_ASSERT(gc_jd_queue_dequeue(&queue) == 0); + + gc_jd_queue_enqueue(&queue, &jds[0]); + CPPUNIT_ASSERT_EQUAL(&jds[0], gc_jd_queue_dequeue(&queue)); + + CPPUNIT_ASSERT(gc_jd_queue_dequeue(&queue) == 0); + + for (int i = 0; i < NJDS; i++) + gc_jd_queue_enqueue(&queue, &jds[i]); + + for (int i = 0; i < NJDS; i++) + CPPUNIT_ASSERT_EQUAL(&jds[i], gc_jd_queue_dequeue(&queue)); + + CPPUNIT_ASSERT(gc_jd_queue_dequeue(&queue) == 0); +} + +// FIXME multithreaded (running on PPE) +void +qa_jd_queue::t2() +{ +} + +// FIXME multithreaded (running on PPE & SPE) +void +qa_jd_queue::t3() +{ +} diff --git a/gcell/src/lib/runtime/qa_jd_queue.h b/gcell/src/lib/runtime/qa_jd_queue.h new file mode 100644 index 000000000..5e1aab84f --- /dev/null +++ b/gcell/src/lib/runtime/qa_jd_queue.h @@ -0,0 +1,42 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_QA_JD_QUEUE_H +#define INCLUDED_QA_JD_QUEUE_H + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCase.h> + +class qa_jd_queue : public CppUnit::TestCase { + + CPPUNIT_TEST_SUITE(qa_jd_queue); + CPPUNIT_TEST(t1); + CPPUNIT_TEST(t2); + CPPUNIT_TEST(t3); + CPPUNIT_TEST_SUITE_END(); + + private: + void t1(); + void t2(); + void t3(); +}; + + +#endif /* INCLUDED_QA_JD_QUEUE_H */ diff --git a/gcell/src/lib/runtime/qa_jd_stack.cc b/gcell/src/lib/runtime/qa_jd_stack.cc new file mode 100644 index 000000000..67e97c9a3 --- /dev/null +++ b/gcell/src/lib/runtime/qa_jd_stack.cc @@ -0,0 +1,67 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "qa_jd_stack.h" +#include <cppunit/TestAssert.h> +#include "gc_jd_stack.h" +#include <stdio.h> + + + +static const int NJDS = 8; +static gc_jd_stack_t stack; +static gc_job_desc_t jds[NJDS]; + +// no brainer, single threaded basic checkout +void +qa_jd_stack::t1() +{ + // N.B., stack allocated stuff doesn't obey ((aligned (N))) attributes + //const int NJDS = 8; + //gc_jd_stack_t stack; + //gc_job_desc_t jds[NJDS]; + + //printf("&stack = %p\n", &stack); + //printf("&jds[0] = %p\n", &jds[0]); + //printf("&jds[1] = %p\n", &jds[1]); + + CPPUNIT_ASSERT(((uintptr_t) &stack & 0x7f) == 0); + CPPUNIT_ASSERT(((uintptr_t) &jds[0] & 0x7f) == 0); + CPPUNIT_ASSERT(((uintptr_t) &jds[1] & 0x7f) == 0); + + gc_jd_stack_init(&stack); + + CPPUNIT_ASSERT(gc_jd_stack_pop(&stack) == 0); + + for (int i = 0; i < NJDS; i++) + gc_jd_stack_push(&stack, &jds[i]); + + for (int i = 0; i < NJDS; i++) + CPPUNIT_ASSERT_EQUAL(&jds[NJDS - i - 1], gc_jd_stack_pop(&stack)); + + CPPUNIT_ASSERT(gc_jd_stack_pop(&stack) == 0); +} + +// FIXME multithreaded (running on PPE) +void +qa_jd_stack::t2() +{ +} diff --git a/gcell/src/lib/runtime/qa_jd_stack.h b/gcell/src/lib/runtime/qa_jd_stack.h new file mode 100644 index 000000000..1546bbf9f --- /dev/null +++ b/gcell/src/lib/runtime/qa_jd_stack.h @@ -0,0 +1,42 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_QA_JD_STACK_H +#define INCLUDED_QA_JD_STACK_H + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCase.h> + +class qa_jd_stack : public CppUnit::TestCase { + + CPPUNIT_TEST_SUITE(qa_jd_stack); + CPPUNIT_TEST(t1); + CPPUNIT_TEST(t2); + CPPUNIT_TEST_SUITE_END(); + + private: + void t1(); + void t2(); + +}; + + + +#endif /* INCLUDED_QA_JD_STACK_H */ diff --git a/gcell/src/lib/runtime/qa_job_manager.cc b/gcell/src/lib/runtime/qa_job_manager.cc new file mode 100644 index 000000000..3f2780c52 --- /dev/null +++ b/gcell/src/lib/runtime/qa_job_manager.cc @@ -0,0 +1,798 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "qa_job_manager.h" +#include <cppunit/TestAssert.h> +#include "gc_job_manager.h" +#include <stdexcept> +#include <stdio.h> +#include <time.h> +#include <errno.h> + +#include <malloc.h> + +extern spe_program_handle_t gcell_qa; // handle to embedded SPU executable w/ QA routines + +#if 0 +static void +gc_msleep(unsigned long millisecs) +{ + int r; + struct timespec tv; + tv.tv_sec = millisecs / 1000; + tv.tv_nsec = (millisecs - (tv.tv_sec * 1000)) * 1000000; + + while (1){ + r = nanosleep(&tv, &tv); + if (r == 0) + return; + if (r == -1 && errno == EINTR) + continue; + perror("nanosleep"); + return; + } +} +#endif + +void +qa_job_manager::leak_check(test_t t, const std::string &name) +{ + struct mallinfo before, after; + + before = mallinfo(); + (this->*t)(); + after = mallinfo(); + + size_t delta = after.uordblks - before.uordblks; + if (delta != 0){ + std::cout << name << " leaked memory\n"; + printf(" before.uordblks = %6d\n", before.uordblks); + printf(" after.uordblks = %6d\n", after.uordblks); + printf(" delta = %d\n", after.uordblks - before.uordblks); + } +} + +void +qa_job_manager::t0() +{ + //leak_check(&qa_job_manager::t1_body, "t1-0"); +} + +void +qa_job_manager::t1() +{ + t1_body(); // leaks 800 bytes first time, could be one-time inits + leak_check(&qa_job_manager::t1_body, "t1"); +} + +void +qa_job_manager::t2() +{ + leak_check(&qa_job_manager::t2_body, "t2"); +} + +void +qa_job_manager::t3() +{ + t3_body(); // leaks first time only, could be cppunit + leak_check(&qa_job_manager::t3_body, "t3"); +} + +void +qa_job_manager::t4() +{ + leak_check(&qa_job_manager::t4_body, "t4"); +} + +void +qa_job_manager::t5() +{ + leak_check(&qa_job_manager::t5_body, "t5"); +} + +void +qa_job_manager::t6() +{ + leak_check(&qa_job_manager::t6_body, "t6"); +} + +void +qa_job_manager::t7() +{ + leak_check(&qa_job_manager::t7_body, "t7"); +} + +void +qa_job_manager::t8() +{ + leak_check(&qa_job_manager::t8_body, "t8"); +} + +void +qa_job_manager::t9() +{ + leak_check(&qa_job_manager::t9_body, "t9"); +} + +void +qa_job_manager::t10() +{ + leak_check(&qa_job_manager::t10_body, "t10"); +} + +void +qa_job_manager::t11() +{ + leak_check(&qa_job_manager::t11_body, "t11"); +} + +void +qa_job_manager::t12() +{ + leak_check(&qa_job_manager::t12_body, "t12"); +} + +void +qa_job_manager::t13() +{ + leak_check(&qa_job_manager::t13_body, "t13"); +} + +void +qa_job_manager::t14() +{ + leak_check(&qa_job_manager::t14_body, "t14"); +} + +void +qa_job_manager::t15() +{ + leak_check(&qa_job_manager::t15_body, "t15"); +} + +// ---------------------------------------------------------------- + +void +qa_job_manager::t1_body() +{ + gc_job_manager *mgr; + gc_jm_options opts; + opts.program_handle = &gcell_qa; + mgr = gc_make_job_manager(&opts); + delete mgr; +} + +void +qa_job_manager::t2_body() +{ + gc_job_manager *mgr = 0; + gc_jm_options opts; + opts.program_handle = &gcell_qa; + opts.nspes = 100; + opts.gang_schedule = false; + mgr = gc_make_job_manager(&opts); + delete mgr; +} + +void +qa_job_manager::t3_body() +{ + // This leaks memory the first time it's invoked, but I'm not sure + // if it's us or the underlying exception handling mechanism, or + // cppunit. cppunit is the prime suspect. + +#if 0 + gc_job_manager *mgr = 0; + gc_jm_options opts; + opts.program_handle = &gcell_qa; + opts.nspes = 100; + opts.gang_schedule = true; + CPPUNIT_ASSERT_THROW(mgr = gc_make_job_manager(&opts), std::out_of_range); + delete mgr; +#endif +} + +static void +init_jd(gc_job_desc *jd, gc_proc_id_t proc_id) +{ + jd->proc_id = proc_id; + jd->input.nargs = 0; + jd->output.nargs = 0; + jd->eaa.nargs = 0; +} + +void +qa_job_manager::t4_body() +{ + gc_job_manager *mgr; + gc_jm_options opts; + opts.program_handle = &gcell_qa; + opts.nspes = 1; + mgr = gc_make_job_manager(&opts); + //mgr->set_debug(-1); + static const int NJOBS = 32; + gc_job_desc *jds[NJOBS]; + bool done[NJOBS]; + + gc_proc_id_t gcp_no_such = mgr->lookup_proc("--no-such-proc-name--"); + CPPUNIT_ASSERT_EQUAL(GCP_UNKNOWN_PROC, gcp_no_such); + + gc_proc_id_t gcp_qa_nop = mgr->lookup_proc("qa_nop"); + CPPUNIT_ASSERT(gcp_qa_nop != GCP_UNKNOWN_PROC); + + for (int i = 0; i < NJOBS; i++){ + jds[i] = mgr->alloc_job_desc(); + init_jd(jds[i], gcp_qa_nop); + } + + for (int i = 0; i < NJOBS; i++){ + if (!mgr->submit_job(jds[i])){ + printf("%d: submit_job(jds[%d]) failed, status = %d\n", + __LINE__, i, jds[i]->status); + } + } + + int n = mgr->wait_jobs(NJOBS, jds, done, GC_WAIT_ALL); + CPPUNIT_ASSERT_EQUAL(NJOBS, n); + + for (int i = 0; i < NJOBS; i++){ + mgr->free_job_desc(jds[i]); + } + + delete mgr; +} + +void +qa_job_manager::t5_body() +{ + gc_job_manager *mgr; + gc_jm_options opts; + opts.program_handle = &gcell_qa; + opts.nspes = 0; // use them all + mgr = gc_make_job_manager(&opts); + //mgr->set_debug(-1); + static const int NJOBS = 32; + gc_job_desc *jds[NJOBS]; + bool done[NJOBS]; + + gc_proc_id_t gcp_qa_nop = mgr->lookup_proc("qa_nop"); + + for (int i = 0; i < NJOBS; i++){ + jds[i] = mgr->alloc_job_desc(); + init_jd(jds[i], gcp_qa_nop); + } + + for (int i = 0; i < NJOBS; i++){ + if (!mgr->submit_job(jds[i])){ + printf("%d: submit_job(jds[%d]) failed, status = %d\n", + __LINE__, i, jds[i]->status); + } + } + + int n = mgr->wait_jobs(NJOBS, jds, done, GC_WAIT_ALL); + CPPUNIT_ASSERT_EQUAL(NJOBS, n); + + for (int i = 0; i < NJOBS; i++){ + mgr->free_job_desc(jds[i]); + } + + delete mgr; +} + +void +qa_job_manager::t6_body() +{ + gc_job_manager *mgr; + gc_jm_options opts; + opts.program_handle = &gcell_qa; + opts.nspes = 1; + mgr = gc_make_job_manager(&opts); + gc_proc_id_t gcp_qa_nop = mgr->lookup_proc("qa_nop"); + gc_job_desc *jd = mgr->alloc_job_desc(); + + + // test for success with gcp_qa_nop procedure + init_jd(jd, gcp_qa_nop); + if (!mgr->submit_job(jd)){ + printf("%d: submit_job(jd) failed, status = %d\n", __LINE__, jd->status); + } + else { + mgr->wait_job(jd); + CPPUNIT_ASSERT_EQUAL(JS_OK, jd->status); + } + + // test for JS_UNKNOWN_PROC with bogus procedure + init_jd(jd, -2); + if (!mgr->submit_job(jd)){ + printf("%d: submit_job(jd) failed, status = %d\n", __LINE__, jd->status); + } + else { + mgr->wait_job(jd); + CPPUNIT_ASSERT_EQUAL(JS_UNKNOWN_PROC, jd->status); + } + + mgr->free_job_desc(jd); + delete mgr; +} + +static int +sum_shorts(short *p, int nshorts) +{ + int total = 0; + for (int i = 0; i < nshorts; i++) + total += p[i]; + + return total; +} + +static void +test_sum_shorts(gc_job_manager *mgr, short *buf, int nshorts) +{ + gc_job_desc *jd = mgr->alloc_job_desc(); + gc_proc_id_t gcp_qa_sum_shorts = mgr->lookup_proc("qa_sum_shorts"); + + init_jd(jd, gcp_qa_sum_shorts); + jd->eaa.nargs = 1; + jd->eaa.arg[0].ea_addr = ptr_to_ea(buf); + jd->eaa.arg[0].direction = GCJD_DMA_GET; + jd->eaa.arg[0].get_size = nshorts * sizeof(short); + + + if (!mgr->submit_job(jd)){ + printf("%d: submit_job(jd) failed, status = %d\n", __LINE__, jd->status); + } + else { + mgr->wait_job(jd); + CPPUNIT_ASSERT_EQUAL(JS_OK, jd->status); + int expected = sum_shorts(buf, nshorts); + int actual = jd->output.arg[0].s32; + CPPUNIT_ASSERT_EQUAL(expected, actual); + } + + mgr->free_job_desc(jd); +} + +static const int NS = 32768; +static short short_buf[NS] _AL128; // for known alignment + +// +// test all "get" alignments and sizes +// +void +qa_job_manager::t7_body() +{ + gc_job_manager *mgr; + gc_jm_options opts; + opts.program_handle = &gcell_qa; + opts.nspes = 1; + mgr = gc_make_job_manager(&opts); + + int ea_args_maxsize = mgr->ea_args_maxsize(); + + for (int i = 0; i < NS; i++) // init buffer with known qty + short_buf[i] = 0x1234 + i; + + for (int offset = 0; offset <= 128; offset++){ + for (int len = 0; len <= 128; len++){ + test_sum_shorts(mgr, &short_buf[offset], len); + } + } + + // confirm maximum length + for (int offset = 0; offset <= 64; offset++){ + test_sum_shorts(mgr, &short_buf[offset], ea_args_maxsize/sizeof(short)); + } + + delete mgr; +} + +// +// test "get" args too long +// +void +qa_job_manager::t8_body() +{ + gc_job_manager *mgr; + gc_jm_options opts; + opts.program_handle = &gcell_qa; + opts.nspes = 1; + mgr = gc_make_job_manager(&opts); + gc_job_desc *jd = mgr->alloc_job_desc(); + gc_proc_id_t gcp_qa_sum_shorts = mgr->lookup_proc("qa_sum_shorts"); + + init_jd(jd, gcp_qa_sum_shorts); + jd->eaa.nargs = 1; + jd->eaa.arg[0].ea_addr = 0; + jd->eaa.arg[0].direction = GCJD_DMA_GET; + jd->eaa.arg[0].get_size = 1 << 20; + + if (!mgr->submit_job(jd)){ + printf("%d: submit_job(jd) failed, status = %d\n", __LINE__, jd->status); + } + else { + mgr->wait_job(jd); + CPPUNIT_ASSERT_EQUAL(JS_ARGS_TOO_LONG, jd->status); + } + + mgr->free_job_desc(jd); + delete mgr; +} + +// +// test MAX_ARGS_EA "get" case +// +void +qa_job_manager::t9_body() +{ + static const int N = 127; + static const int M = 201; + gc_job_manager *mgr; + gc_jm_options opts; + opts.program_handle = &gcell_qa; + opts.nspes = 1; + mgr = gc_make_job_manager(&opts); + gc_job_desc *jd = mgr->alloc_job_desc(); + gc_proc_id_t gcp_qa_sum_shorts = mgr->lookup_proc("qa_sum_shorts"); + + init_jd(jd, gcp_qa_sum_shorts); + jd->eaa.nargs = MAX_ARGS_EA; + for (int i = 0; i < MAX_ARGS_EA; i++){ + jd->eaa.arg[i].direction = GCJD_DMA_GET; + jd->eaa.arg[i].ea_addr = ptr_to_ea(&short_buf[i * M]); + jd->eaa.arg[i].get_size = N * sizeof(short); + } + + if (!mgr->submit_job(jd)){ + printf("%d: submit_job(jd) failed, status = %d\n", __LINE__, jd->status); + } + else { + mgr->wait_job(jd); + CPPUNIT_ASSERT_EQUAL(JS_OK, jd->status); + for (int i = 0; i < MAX_ARGS_EA; i++){ + int expected = sum_shorts(&short_buf[i * M], N); + int actual = jd->output.arg[i].s32; + CPPUNIT_ASSERT_EQUAL(expected, actual); + } + } + + mgr->free_job_desc(jd); + delete mgr; +} + +static bool +confirm_const(const unsigned char *buf, size_t len, unsigned char v) +{ + bool ok = true; + + for (size_t i = 0; i < len; i++){ + if (buf[i] != v){ + ok = false; + printf("confirm_const: buf[%6d] = 0x%02x, expected = 0x%02x\n", + i, buf[i], v); + } + } + + return ok; +} + +static bool +confirm_seq(const unsigned char *buf, size_t len, unsigned char v) +{ + bool ok = true; + + for (size_t i = 0; i < len; i++, v++){ + if (buf[i] != v){ + ok = false; + printf("confirm_seq: buf[%6d] = 0x%02x, expected = 0x%02x\n", + i, buf[i], v); + } + } + + return ok; +} + +static void +test_put_seq(gc_job_manager *mgr, int offset, int len, int starting_val) +{ + gc_job_desc *jd = mgr->alloc_job_desc(); + gc_proc_id_t gcp_qa_put_seq = mgr->lookup_proc("qa_put_seq"); + + unsigned char *buf = (unsigned char *) short_buf; + size_t buf_len = sizeof(short_buf); + memset(buf, 0xff, buf_len); + + // two cache lines into the buffer, so we can check before and after + int fixed_offset = 256; + + init_jd(jd, gcp_qa_put_seq); + jd->input.nargs = 1; + jd->input.arg[0].s32 = starting_val; + jd->eaa.nargs = 1; + jd->eaa.arg[0].ea_addr = ptr_to_ea(buf + fixed_offset + offset); + jd->eaa.arg[0].direction = GCJD_DMA_PUT; + jd->eaa.arg[0].put_size = len; + + if (!mgr->submit_job(jd)){ + printf("%d: submit_job(jd) failed, status = %d\n", __LINE__, jd->status); + } + else { + mgr->wait_job(jd); + CPPUNIT_ASSERT_EQUAL(JS_OK, jd->status); + + // check before + CPPUNIT_ASSERT(confirm_const(&buf[0], fixed_offset + offset, 0xff)); + + // check sequence + CPPUNIT_ASSERT(confirm_seq(&buf[fixed_offset + offset], len, starting_val)); + + // check after + CPPUNIT_ASSERT(confirm_const(&buf[fixed_offset + offset + len], + buf_len - fixed_offset - offset - len, 0xff)); + } + mgr->free_job_desc(jd); +} + +// +// Test all "put" alignments and sizes +// +void +qa_job_manager::t10_body() +{ + gc_job_manager *mgr; + gc_jm_options opts; + opts.program_handle = &gcell_qa; + opts.nspes = 1; + mgr = gc_make_job_manager(&opts); + + int starting_val = 13; + + for (int offset = 0; offset <= 128; offset++){ + for (int len = 0; len <= 128; len++){ + test_put_seq(mgr, offset, len, starting_val++); + } + } + + int ea_args_maxsize = mgr->ea_args_maxsize(); + + // confirm maximum length + for (int offset = 0; offset <= 64; offset++){ + test_put_seq(mgr, offset, ea_args_maxsize, starting_val++); + } + + delete mgr; +} + +// +// test "put" args too long +// +void +qa_job_manager::t11_body() +{ + gc_job_manager *mgr; + gc_jm_options opts; + opts.program_handle = &gcell_qa; + opts.nspes = 1; + mgr = gc_make_job_manager(&opts); + gc_job_desc *jd = mgr->alloc_job_desc(); + gc_proc_id_t gcp_qa_put_seq = mgr->lookup_proc("qa_put_seq"); + + init_jd(jd, gcp_qa_put_seq); + jd->input.nargs = 1; + jd->input.arg[0].s32 = 0; + jd->eaa.nargs = 1; + jd->eaa.arg[0].ea_addr = 0; + jd->eaa.arg[0].direction = GCJD_DMA_PUT; + jd->eaa.arg[0].put_size = 1 << 20; + + if (!mgr->submit_job(jd)){ + printf("%d: submit_job(jd) failed, status = %d\n", __LINE__, jd->status); + } + else { + mgr->wait_job(jd); + CPPUNIT_ASSERT_EQUAL(JS_ARGS_TOO_LONG, jd->status); + } + + mgr->free_job_desc(jd); + delete mgr; +} + +// +// test MAX_ARGS_EA "put" case +// +void +qa_job_manager::t12_body() +{ + static const int N = 127; + static const int M = 201; + gc_job_manager *mgr; + gc_jm_options opts; + opts.program_handle = &gcell_qa; + opts.nspes = 1; + mgr = gc_make_job_manager(&opts); + gc_job_desc *jd = mgr->alloc_job_desc(); + gc_proc_id_t gcp_qa_put_seq = mgr->lookup_proc("qa_put_seq"); + + unsigned char *buf = (unsigned char *) short_buf; + size_t buf_len = sizeof(short_buf); + memset(buf, 0xff, buf_len); + + // two cache lines into the buffer, so we can check before and after + int fixed_offset = 256; + + int starting_val = 13; + + init_jd(jd, gcp_qa_put_seq); + jd->input.nargs = 1; + jd->input.arg[0].s32 = starting_val; + jd->eaa.nargs = MAX_ARGS_EA; + for (int i = 0; i < MAX_ARGS_EA; i++){ + jd->eaa.arg[i].direction = GCJD_DMA_PUT; + jd->eaa.arg[i].ea_addr = ptr_to_ea(&buf[i * M + fixed_offset]); + jd->eaa.arg[i].put_size = N; + } + + if (!mgr->submit_job(jd)){ + printf("%d: submit_job(jd) failed, status = %d\n", __LINE__, jd->status); + } + else { + mgr->wait_job(jd); + CPPUNIT_ASSERT_EQUAL(JS_OK, jd->status); + for (int i = 0; i < MAX_ARGS_EA; i++){ + CPPUNIT_ASSERT(confirm_seq(&buf[i * M + fixed_offset], N, starting_val)); + starting_val += N; + } + } + + mgr->free_job_desc(jd); + delete mgr; +} + +// +// test qa_copy primitive +// +void +qa_job_manager::t13_body() +{ + gc_job_manager *mgr; + gc_jm_options opts; + opts.program_handle = &gcell_qa; + opts.nspes = 1; + mgr = gc_make_job_manager(&opts); + + memset(short_buf, 0, sizeof(short_buf)); + for (int i = 0; i < NS/2; i++) // init buffer with known qty + short_buf[i] = 0x1234 + i; + + int nshorts = NS/2; + + gc_job_desc *jd = mgr->alloc_job_desc(); + gc_proc_id_t gcp_qa_copy = mgr->lookup_proc("qa_copy"); + +#if 0 + printf("gcq_qa_copy = %d\n", gcp_qa_copy); + std::vector<std::string> procs = mgr->proc_names(); + for (unsigned int i = 0; i < procs.size(); ++i) + std::cout << procs[i] << std::endl; +#endif + + init_jd(jd, gcp_qa_copy); + jd->eaa.nargs = 2; + jd->eaa.arg[0].ea_addr = ptr_to_ea(&short_buf[nshorts]); + jd->eaa.arg[0].direction = GCJD_DMA_PUT; + jd->eaa.arg[0].put_size = nshorts * sizeof(short); + + jd->eaa.arg[1].ea_addr = ptr_to_ea(&short_buf[0]); + jd->eaa.arg[1].direction = GCJD_DMA_GET; + jd->eaa.arg[1].get_size = nshorts * sizeof(short); + + + if (!mgr->submit_job(jd)){ + printf("%d: submit_job(jd) failed, status = %d\n", __LINE__, jd->status); + } + else { + mgr->wait_job(jd); + CPPUNIT_ASSERT_EQUAL(JS_OK, jd->status); + CPPUNIT_ASSERT_EQUAL(0, jd->output.arg[0].s32); + + bool ok = true; + for (int i = 0; i < nshorts; i++){ + if (short_buf[i] != short_buf[i + nshorts]) + ok = false; + } + CPPUNIT_ASSERT(ok); + } + mgr->free_job_desc(jd); + + delete mgr; +} + +/* + * Parallel submission of NJOBS "put" jobs will test double buffered puts. + */ +void +qa_job_manager::t14_body() +{ + //return; + + //static const int NJOBS = 64; + static const int NJOBS = 128; + static const int LEN_PER_JOB = 1021; + unsigned char buf[NJOBS * LEN_PER_JOB]; + gc_job_desc_t *jd[NJOBS]; + bool done[NJOBS]; + + static const int STARTING_VAL = 13; + + memset(buf, 0xff, LEN_PER_JOB * NJOBS); + + gc_job_manager *mgr; + gc_jm_options opts; + opts.program_handle = &gcell_qa; + opts.nspes = 1; + mgr = gc_make_job_manager(&opts); + + + gc_proc_id_t gcp_qa_put_seq = mgr->lookup_proc("qa_put_seq"); + + // do all the initialization up front + + for (int i = 0, val = STARTING_VAL; i < NJOBS; i++, val += 3){ + jd[i] = mgr->alloc_job_desc(); + init_jd(jd[i], gcp_qa_put_seq); + jd[i]->input.nargs = 1; + jd[i]->input.arg[0].s32 = val; + jd[i]->eaa.nargs = 1; + jd[i]->eaa.arg[0].ea_addr = ptr_to_ea(&buf[i * LEN_PER_JOB]); + jd[i]->eaa.arg[0].direction = GCJD_DMA_PUT; + jd[i]->eaa.arg[0].put_size = LEN_PER_JOB; + } + + // submit them all + + for (int i = 0; i < NJOBS; i++){ + if (!mgr->submit_job(jd[i])){ + printf("%d: submit_job(jd[%2d]) failed, status = %d\n", __LINE__, i, jd[i]->status); + } + } + + // wait for them all + + int n = mgr->wait_jobs(NJOBS, jd, done, GC_WAIT_ALL); + CPPUNIT_ASSERT_EQUAL(NJOBS, n); + + // check results + + for (int i = 0, val = STARTING_VAL; i < NJOBS; i++, val += 3){ + CPPUNIT_ASSERT_EQUAL(JS_OK, jd[i]->status); + CPPUNIT_ASSERT(confirm_seq(&buf[i * LEN_PER_JOB], LEN_PER_JOB, val)); + } + + // cleanup + for (int i = 0; i < NJOBS; i++) + mgr->free_job_desc(jd[i]); + + delete mgr; +} + +void +qa_job_manager::t15_body() +{ +} diff --git a/gcell/src/lib/runtime/qa_job_manager.h b/gcell/src/lib/runtime/qa_job_manager.h new file mode 100644 index 000000000..ab3325b73 --- /dev/null +++ b/gcell/src/lib/runtime/qa_job_manager.h @@ -0,0 +1,89 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_QA_JOB_MANAGER_H +#define INCLUDED_QA_JOB_MANAGER_H + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCase.h> + +class qa_job_manager; +typedef void (qa_job_manager::*test_t)(); + + +class qa_job_manager : public CppUnit::TestCase { + + CPPUNIT_TEST_SUITE(qa_job_manager); + CPPUNIT_TEST(t0); + CPPUNIT_TEST(t1); + CPPUNIT_TEST(t2); + CPPUNIT_TEST(t3); + CPPUNIT_TEST(t4); + CPPUNIT_TEST(t5); + CPPUNIT_TEST(t6); + CPPUNIT_TEST(t7); + CPPUNIT_TEST(t8); + CPPUNIT_TEST(t9); + CPPUNIT_TEST(t10); + CPPUNIT_TEST(t11); + CPPUNIT_TEST(t12); + CPPUNIT_TEST(t13); + CPPUNIT_TEST(t14); + CPPUNIT_TEST(t15); + CPPUNIT_TEST_SUITE_END(); + + private: + void leak_check(test_t t, const std::string &name); + + void t0(); + void t1(); + void t1_body(); + void t2(); + void t2_body(); + void t3(); + void t3_body(); + void t4(); + void t4_body(); + void t5(); + void t5_body(); + void t6(); + void t6_body(); + void t7(); + void t7_body(); + void t8(); + void t8_body(); + void t9(); + void t9_body(); + void t10(); + void t10_body(); + void t11(); + void t11_body(); + void t12(); + void t12_body(); + void t13(); + void t13_body(); + void t14(); + void t14_body(); + void t15(); + void t15_body(); + +}; + +#endif /* INCLUDED_QA_JOB_MANAGER_H */ diff --git a/gcell/src/lib/runtime/qa_lib.cc b/gcell/src/lib/runtime/qa_lib.cc new file mode 100644 index 000000000..d8a8960c6 --- /dev/null +++ b/gcell/src/lib/runtime/qa_lib.cc @@ -0,0 +1,43 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/* + * This class gathers together all the test cases for the lib + * directory into a single test suite. As you create new test cases, + * add them here. + */ + +#include <qa_lib.h> +#include <qa_jd_stack.h> +#include <qa_jd_queue.h> +#include <qa_job_manager.h> + +CppUnit::TestSuite * +qa_lib::suite() +{ + CppUnit::TestSuite *s = new CppUnit::TestSuite("lib"); + + s->addTest(qa_jd_stack::suite()); + s->addTest(qa_jd_queue::suite()); + s->addTest(qa_job_manager::suite()); + + return s; +} diff --git a/gcell/src/lib/runtime/qa_lib.h b/gcell/src/lib/runtime/qa_lib.h new file mode 100644 index 000000000..594efcdc8 --- /dev/null +++ b/gcell/src/lib/runtime/qa_lib.h @@ -0,0 +1,35 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_QA_LIB_H +#define INCLUDED_QA_LIB_H + +#include <cppunit/TestSuite.h> + +//! collect all the tests for the lib directory + +class qa_lib { +public: + //! return suite of tests + static CppUnit::TestSuite *suite(); +}; + + +#endif /* INCLUDED_QA_LIB_H */ diff --git a/gcell/src/lib/runtime/spu/gc_delay.c b/gcell/src/lib/runtime/spu/gc_delay.c new file mode 100644 index 000000000..21ee587f8 --- /dev/null +++ b/gcell/src/lib/runtime/spu/gc_delay.c @@ -0,0 +1,58 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "gc_delay.h" +#include <compiler.h> + +inline static void +gc_udelay_1us(void) +{ + unsigned int i = 158; + + do { // 20 clocks per iteration of the loop + asm ("nop $127; nop $127; nop $127; nop $127; nop $127"); + asm ("nop $127; nop $127; nop $127; nop $127; nop $127"); + asm ("nop $127; nop $127; nop $127; nop $127; nop $127"); + asm ("nop $127; nop $127"); + } while(--i != 0); +} + +void +gc_udelay(unsigned int usecs) +{ + unsigned int i; + for (i = 0; i < usecs; i++) + gc_udelay_1us(); +} + +void +gc_cdelay(unsigned int cpu_cycles) +{ + if (cpu_cycles < 40) // roughly the amount of overhead + return; + + cpu_cycles >>= 2; // about 4 cycles / loop + + while (cpu_cycles-- != 0){ + asm ("nop $127"); // keeps compiler from removing the loop + } +} + diff --git a/gcell/src/lib/runtime/spu/gc_logging.c b/gcell/src/lib/runtime/spu/gc_logging.c new file mode 100644 index 000000000..65a537504 --- /dev/null +++ b/gcell/src/lib/runtime/spu/gc_logging.c @@ -0,0 +1,77 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <gc_logging.h> +#include <spu_intrinsics.h> +#include <spu_mfcio.h> +#include <gc_spu_args.h> + +static gc_eaddr_t log_base_ea; // base address of log entries in EA +static uint32_t log_idx_mask; // nentries - 1 +static uint32_t log_idx; // current log entry index +static uint32_t log_seqno; + +static int log_tags; // two consecutive tags +static int tmp_buffer_busy; // bitmask: buffer busy state +static int tmp_buffer_idx; // 0 or 1 +static gc_log_entry_t tmp_buffer[2]; + +void +_gc_log_init(gc_log_t info) +{ + spu_write_decrementer(~0); + + log_base_ea = info.base; + log_idx_mask = info.nentries - 1; + log_idx = 0; + log_seqno = 0; + + log_tags = mfc_multi_tag_reserve(2); + tmp_buffer_busy = 0; + tmp_buffer_idx = 0; + + gc_log_write0(GCL_SS_SYS, 0); +} + +void +_gc_log_write(gc_log_entry_t entry) +{ + if (log_base_ea == 0) + return; + + entry.seqno = log_seqno++; + entry.timestamp = spu_read_decrementer(); + + if (tmp_buffer_busy & (1 << tmp_buffer_idx)){ + mfc_write_tag_mask(1 << (log_tags + tmp_buffer_idx)); + mfc_read_tag_status_all(); + } + + tmp_buffer[tmp_buffer_idx] = entry; // save local copy + + mfc_put(&tmp_buffer[tmp_buffer_idx], + log_base_ea + log_idx * sizeof(entry), sizeof(entry), + log_tags + tmp_buffer_idx, 0, 0); + + tmp_buffer_busy |= (1 << tmp_buffer_idx); + tmp_buffer_idx ^= 0x1; + log_idx = (log_idx + 1) & log_idx_mask; +} diff --git a/gcell/src/lib/runtime/spu/gc_main.c b/gcell/src/lib/runtime/spu/gc_main.c new file mode 100644 index 000000000..96381fa66 --- /dev/null +++ b/gcell/src/lib/runtime/spu/gc_main.c @@ -0,0 +1,682 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#define ENABLE_GC_LOGGING // define to enable logging + +#include <spu_intrinsics.h> +#include <spu_mfcio.h> +#include <sync_utils.h> +#include "gc_spu_config.h" +#include "gc_spu_args.h" +#include "gc_job_desc.h" +#include "gc_mbox.h" +#include "gc_jd_queue.h" +#include "gc_delay.h" +#include "gc_declare_proc.h" +#include "spu_buffers.h" +#include <string.h> +#include <assert.h> +#include <stdio.h> + + +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) + +//! round x down to p2 boundary (p2 must be a power-of-2) +#define ROUND_DN(x, p2) ((x) & ~((p2)-1)) + +//! round x up to p2 boundary (p2 must be a power-of-2) +#define ROUND_UP(x, p2) (((x)+((p2)-1)) & ~((p2)-1)) + + +#define USE_LLR_LOST_EVENT 0 // define to 0 or 1 + +int gc_sys_tag; // tag for misc DMA operations +static gc_spu_args_t spu_args; + +static struct gc_proc_def *gc_proc_def; // procedure entry points + +// ------------------------------------------------------------------------ + +// state for DMA'ing arguments in and out + +static int get_tag; // 1 tag for job arg gets +static int put_tags; // 2 tags for job arg puts + +static int pb_idx = 0; // current put buffer index (0 or 1) + +// bitmask (bit per put buffer): bit is set if DMA is started but not complete +static int put_in_progress = 0; +#define PBI_MASK(_pbi_) (1 << (_pbi_)) + +// ------------------------------------------------------------------------ + +// our working copy of the completion info +static gc_comp_info_t comp_info = { + .in_use = 1, + .ncomplete = 0 +}; + +static int ci_idx = 0; // index of current comp_info +static int ci_tags; // two consecutive dma tags + +// ------------------------------------------------------------------------ + +/* + * Wait until EA copy of comp_info[idx].in_use is 0 + */ +static void +wait_for_ppe_to_be_done_with_comp_info(int idx) +{ + char _tmp[256]; + char *buf = (char *) ALIGN(_tmp, 128); // get cache-aligned buffer + gc_comp_info_t *p = (gc_comp_info_t *) buf; + + assert(sizeof(gc_comp_info_t) == 128); + + do { + mfc_get(buf, spu_args.comp_info[idx], 128, gc_sys_tag, 0, 0); + mfc_write_tag_mask(1 << gc_sys_tag); + mfc_read_tag_status_all(); + if (p->in_use == 0) + return; + + gc_udelay(5); + + } while (1); +} + +static void +flush_completion_info(void) +{ + // events: 0x3X + + static int total_complete = 0; + + if (comp_info.ncomplete == 0) + return; + + // ensure that PPE is done with the buffer we're about to overwrite + wait_for_ppe_to_be_done_with_comp_info(ci_idx); + + // dma the comp_info out to PPE + int tag = ci_tags + ci_idx; + mfc_put(&comp_info, spu_args.comp_info[ci_idx], sizeof(gc_comp_info_t), tag, 0, 0); + + // we need to wait for the completion info to finish, as well as + // any EA argument puts. + + int tag_mask = 1 << tag; // the comp_info tag + if (put_in_progress & PBI_MASK(0)) + tag_mask |= (1 << (put_tags + 0)); + if (put_in_progress & PBI_MASK(1)) + tag_mask |= (1 << (put_tags + 1)); + + gc_log_write2(GCL_SS_SYS, 0x30, put_in_progress, tag_mask); + + mfc_write_tag_mask(tag_mask); // the tags we're interested in + mfc_read_tag_status_all(); // wait for DMA to complete + put_in_progress = 0; // mark them all complete + + total_complete += comp_info.ncomplete; + gc_log_write4(GCL_SS_SYS, 0x31, + put_in_progress, ci_idx, comp_info.ncomplete, total_complete); + + // send PPE a message + spu_writech(SPU_WrOutIntrMbox, MK_MBOX_MSG(OP_JOBS_DONE, ci_idx)); + + ci_idx ^= 0x1; // switch buffers + comp_info.in_use = 1; + comp_info.ncomplete = 0; +} + +// ------------------------------------------------------------------------ + +static unsigned int backoff; // current backoff value in clock cycles +static unsigned int _backoff_start; +static unsigned int _backoff_cap; + +/* + * For 3.2 GHz SPE + * + * 12 4095 cycles 1.3 us + * 13 8191 cycles 2.6 us + * 14 16383 cycles 5.1 us + * 15 32767 cycles 10.2 us + * 16 20.4 us + * 17 40.8 us + * 18 81.9 us + * 19 163.8 us + * 20 327.7 us + * 21 655.4 us + */ +static unsigned char log2_backoff_start[16] = { +// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 +// ------------------------------------------------------------- + 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 16, 16 +}; + +static unsigned char log2_backoff_cap[16] = { +// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 +// ------------------------------------------------------------- + 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 21, 21 +}; + +static void +backoff_init(void) +{ + _backoff_cap = (1 << (log2_backoff_cap[(spu_args.nspus - 1) & 0xf])) - 1; + _backoff_start = (1 << (log2_backoff_start[(spu_args.nspus - 1) & 0xf])) - 1; + + backoff = _backoff_start; +} + +static void +backoff_reset(void) +{ + backoff = _backoff_start; +} + +static void +backoff_delay(void) +{ + gc_cdelay(backoff); + + // capped exponential backoff + backoff = ((backoff << 1) + 1) & _backoff_cap; +} + +// ------------------------------------------------------------------------ + +static inline unsigned int +make_mask(int nbits) +{ + return ~(~0 << nbits); +} + +static unsigned int dc_work; +static int dc_put_tag; +static unsigned char *dc_ls_base; +static gc_eaddr_t dc_ea_base; + +// divide and conquer +static void +d_and_c(unsigned int offset, unsigned int len) +{ + unsigned int mask = make_mask(len) << offset; + unsigned int t = mask & dc_work; + if (t == 0) // nothing to do + return; + if (t == mask){ // got a match, generate dma + mfc_put(dc_ls_base + offset, dc_ea_base + offset, len, dc_put_tag, 0, 0); + } + else { // bisect + len >>= 1; + d_and_c(offset, len); + d_and_c(offset + len, len); + } +} + +// Handle the nasty case of a dma xfer that's less than 16 bytes long. +// len is guaranteed to be in [1, 15] + +static void +handle_slow_and_tedious_dma(gc_eaddr_t ea, unsigned char *ls, + unsigned int len, int put_tag) +{ + // Set up for divide and conquer + unsigned int alignment = ((uintptr_t) ls) & 0x7; + dc_work = make_mask(len) << alignment; + dc_ls_base = (unsigned char *) ROUND_DN((uintptr_t) ls, 8); + dc_ea_base = ROUND_DN(ea, (gc_eaddr_t) 8); + dc_put_tag = put_tag; + + d_and_c( 0, 8); + d_and_c( 8, 8); + d_and_c(16, 8); +} + + +static void +process_job(gc_eaddr_t jd_ea, gc_job_desc_t *jd) +{ + // events: 0x2X + + jd->status = JS_OK; // assume success + + if (jd->proc_id >= spu_args.nproc_defs) + jd->status = JS_UNKNOWN_PROC; + + else { + + if (jd->eaa.nargs == 0) + (*gc_proc_def[jd->proc_id].proc)(&jd->input, &jd->output, &jd->eaa); + + else { // handle EA args that must be DMA'd in/out + + gc_job_ea_args_t *eaa = &jd->eaa; + + int NELMS = + MAX(MAX_ARGS_EA, + (GC_SPU_BUFSIZE + MFC_MAX_DMA_SIZE - 1) / MFC_MAX_DMA_SIZE); + + mfc_list_element_t dma_get_list[NELMS]; + //mfc_list_element_t dma_put_list[NELMS]; + + memset(dma_get_list, 0, sizeof(dma_get_list)); + //memset(dma_put_list, 0, sizeof(dma_put_list)); + + int gli = 0; // get list index + //int pli = 0; // put list index + + unsigned char *get_base = _gci_getbuf[0]; + unsigned char *get_t = get_base; + unsigned int total_get_dma_len = 0; + + unsigned char *put_base = _gci_putbuf[pb_idx]; + unsigned char *put_t = put_base; + unsigned int total_put_alloc = 0; + int put_tag = put_tags + pb_idx; + + // Do we have any "put" args? If so ensure that previous + // dma from this buffer is complete + + gc_log_write2(GCL_SS_SYS, 0x24, put_in_progress, jd->sys.direction_union); + + if ((jd->sys.direction_union & GCJD_DMA_PUT) + && (put_in_progress & PBI_MASK(pb_idx))){ + + gc_log_write2(GCL_SS_SYS, 0x25, put_in_progress, 1 << put_tag); + + mfc_write_tag_mask(1 << put_tag); // the tag we're interested in + mfc_read_tag_status_all(); // wait for DMA to complete + put_in_progress &= ~(PBI_MASK(pb_idx)); + + gc_log_write1(GCL_SS_SYS, 0x26, put_in_progress); + } + + + // for now, all EA's must have the same high 32-bits + gc_eaddr_t common_ea = eaa->arg[0].ea_addr; + + + // assign LS addresses for buffers + + for (unsigned int i = 0; i < eaa->nargs; i++){ + + gc_eaddr_t ea_base = 0; + unsigned char *ls_base; + int offset; + unsigned int dma_len; + + if (eaa->arg[i].direction == GCJD_DMA_GET){ + ea_base = ROUND_DN(eaa->arg[i].ea_addr, (gc_eaddr_t) CACHE_LINE_SIZE); + offset = eaa->arg[i].ea_addr & (CACHE_LINE_SIZE-1); + dma_len = ROUND_UP(eaa->arg[i].get_size + offset, CACHE_LINE_SIZE); + total_get_dma_len += dma_len; + + if (total_get_dma_len > GC_SPU_BUFSIZE){ + jd->status = JS_ARGS_TOO_LONG; + goto wrap_up; + } + + ls_base = get_t; + get_t += dma_len; + eaa->arg[i].ls_addr = ls_base + offset; + + if (0){ + assert((mfc_ea2l(eaa->arg[i].ea_addr) & 0x7f) == ((intptr_t)eaa->arg[i].ls_addr & 0x7f)); + assert((ea_base & 0x7f) == 0); + assert(((intptr_t)ls_base & 0x7f) == 0); + assert((dma_len & 0x7f) == 0); + assert((eaa->arg[i].get_size <= dma_len) + && dma_len <= (eaa->arg[i].get_size + offset + CACHE_LINE_SIZE - 1)); + } + + // add to dma get list + // FIXME (someday) the dma list is where the JS_BAD_EAH limitation comes from + + while (dma_len != 0){ + int n = MIN(dma_len, MFC_MAX_DMA_SIZE); + dma_get_list[gli].size = n; + dma_get_list[gli].eal = mfc_ea2l(ea_base); + dma_len -= n; + ea_base += n; + gli++; + } + } + + else if (eaa->arg[i].direction == GCJD_DMA_PUT){ + // + // This case is a trickier than the PUT case since we can't + // write outside of the bounds of the user provided buffer. + // We still align the buffers to 128-bytes for good performance + // in the middle portion of the xfers. + // + ea_base = ROUND_DN(eaa->arg[i].ea_addr, (gc_eaddr_t) CACHE_LINE_SIZE); + offset = eaa->arg[i].ea_addr & (CACHE_LINE_SIZE-1); + + uint32_t ls_alloc_len = + ROUND_UP(eaa->arg[i].put_size + offset, CACHE_LINE_SIZE); + + total_put_alloc += ls_alloc_len; + + if (total_put_alloc > GC_SPU_BUFSIZE){ + jd->status = JS_ARGS_TOO_LONG; + goto wrap_up; + } + + ls_base = put_t; + put_t += ls_alloc_len; + eaa->arg[i].ls_addr = ls_base + offset; + + if (1){ + assert((mfc_ea2l(eaa->arg[i].ea_addr) & 0x7f) + == ((intptr_t)eaa->arg[i].ls_addr & 0x7f)); + assert((ea_base & 0x7f) == 0); + assert(((intptr_t)ls_base & 0x7f) == 0); + } + } + + else + assert(0); + } + + // fire off the dma to fetch the args and wait for it to complete + mfc_getl(get_base, common_ea, dma_get_list, gli*sizeof(dma_get_list[0]), get_tag, 0, 0); + mfc_write_tag_mask(1 << get_tag); // the tag we're interested in + mfc_read_tag_status_all(); // wait for DMA to complete + + // do the work + (*gc_proc_def[jd->proc_id].proc)(&jd->input, &jd->output, &jd->eaa); + + + // Do we have any "put" args? If so copy them out + if (jd->sys.direction_union & GCJD_DMA_PUT){ + + // Do the copy out using single DMA xfers. The LS ranges + // aren't generally contiguous. + + bool started_dma = false; + + for (unsigned int i = 0; i < eaa->nargs; i++){ + if (eaa->arg[i].direction == GCJD_DMA_PUT && eaa->arg[i].put_size != 0){ + + started_dma = true; + + gc_eaddr_t ea; + unsigned char *ls; + unsigned int len; + + ea = eaa->arg[i].ea_addr; + ls = (unsigned char *) eaa->arg[i].ls_addr; + len = eaa->arg[i].put_size; + + if (len < 16) + handle_slow_and_tedious_dma(ea, ls, len, put_tag); + + else { + if ((ea & 0xf) != 0){ + + // printf("1: ea = 0x%x len = %5d\n", (int) ea, len); + + // handle the "pre-multiple-of-16" portion + // do 1, 2, 4, or 8 byte xfers as required + + if (ea & 0x1){ // do a 1-byte xfer + mfc_put(ls, ea, 1, put_tag, 0, 0); + ea += 1; + ls += 1; + len -= 1; + } + if (ea & 0x2){ // do a 2-byte xfer + mfc_put(ls, ea, 2, put_tag, 0, 0); + ea += 2; + ls += 2; + len -= 2; + } + if (ea & 0x4){ // do a 4-byte xfer + mfc_put(ls, ea, 4, put_tag, 0, 0); + ea += 4; + ls += 4; + len -= 4; + } + if (ea & 0x8){ // do an 8-byte xfer + mfc_put(ls, ea, 8, put_tag, 0, 0); + ea += 8; + ls += 8; + len -= 8; + } + } + + if (1){ + // printf("2: ea = 0x%x len = %5d\n", (int) ea, len); + assert((ea & 0xf) == 0); + assert((((intptr_t) ls) & 0xf) == 0); + } + + // handle the "multiple-of-16" portion + + int aligned_len = ROUND_DN(len, 16); + len = len & (16 - 1); + + while (aligned_len != 0){ + int dma_len = MIN(aligned_len, MFC_MAX_DMA_SIZE); + mfc_put(ls, ea, dma_len, put_tag, 0, 0); + ea += dma_len; + ls += dma_len; + aligned_len -= dma_len; + } + + if (1){ + // printf("3: ea = 0x%x len = %5d\n", (int)ea, len); + assert((ea & 0xf) == 0); + assert((((intptr_t) ls) & 0xf) == 0); + } + + // handle "post-multiple-of-16" portion + + if (len != 0){ + + if (len >= 8){ // do an 8-byte xfer + mfc_put(ls, ea, 8, put_tag, 0, 0); + ea += 8; + ls += 8; + len -= 8; + } + if (len >= 4){ // do a 4-byte xfer + mfc_put(ls, ea, 4, put_tag, 0, 0); + ea += 4; + ls += 4; + len -= 4; + } + if (len >= 2){ // do a 2-byte xfer + mfc_put(ls, ea, 2, put_tag, 0, 0); + ea += 2; + ls += 2; + len -= 2; + } + if (len >= 1){ // do a 1-byte xfer + mfc_put(ls, ea, 1, put_tag, 0, 0); + ea += 1; + ls += 1; + len -= 1; + } + if (1) + assert(len == 0); + } + } + } + } + if (started_dma){ + put_in_progress |= PBI_MASK(pb_idx); // note it's running + gc_log_write2(GCL_SS_SYS, 0x27, put_in_progress, pb_idx); + pb_idx ^= 1; // toggle current buffer + } + } + } + } + + wrap_up:; // semicolon creates null statement for C99 compliance + + // Copy job descriptor back out to EA. + // (The dma will be waited on in flush_completion_info) + int tag = ci_tags + ci_idx; // use the current completion tag + mfc_put(jd, jd_ea, sizeof(*jd), tag, 0, 0); + + mfc_sync(tag); // FIXME this makes it work, but is expensive + + + // Tell PPE we're done with the job. + // + // We queue these up until we run out of room, or until we can send + // the info to the PPE w/o blocking. The blocking check is in + // main_loop + + comp_info.job_id[comp_info.ncomplete++] = jd->sys.job_id; + + if (comp_info.ncomplete == GC_CI_NJOBS){ + gc_log_write0(GCL_SS_SYS, 0x28); + flush_completion_info(); + } +} + +static void +main_loop(void) +{ + // events: 0x1X + + static gc_job_desc_t jd; // static gets us proper alignment + gc_eaddr_t jd_ea; + int total_jobs = 0; + + // setup events + spu_writech(SPU_WrEventMask, MFC_LLR_LOST_EVENT); + gc_jd_queue_getllar(spu_args.queue); // get a line reservation on the queue + + while (1){ + +#if (USE_LLR_LOST_EVENT) + + if (unlikely(spu_readchcnt(SPU_RdEventStat))){ + // + // execute standard event handling prologue + // + int status = spu_readch(SPU_RdEventStat); + int mask = spu_readch(SPU_RdEventMask); + spu_writech(SPU_WrEventMask, mask & ~status); // disable active events + spu_writech(SPU_WrEventAck, status); // ack active events + + // execute per-event actions + + if (status & MFC_LLR_LOST_EVENT){ + // + // We've lost a line reservation. This is most likely caused + // by somebody doing something to the queue. Go look and see + // if there's anything for us. + // + if (gc_jd_queue_dequeue(spu_args.queue, &jd_ea, &jd)) + process_job(jd_ea, &jd); + + gc_jd_queue_getllar(spu_args.queue); // get a new reservation + } + + // + // execute standard event handling epilogue + // + spu_writech(SPU_WrEventMask, mask); // restore event mask + } + +#else + + // try to get a job from the job queue + if (gc_jd_queue_dequeue(spu_args.queue, &jd_ea, &jd)){ + total_jobs++; + gc_log_write2(GCL_SS_SYS, 0x10, jd.sys.job_id, total_jobs); + + process_job(jd_ea, &jd); + + gc_log_write2(GCL_SS_SYS, 0x11, jd.sys.job_id, total_jobs); + backoff_reset(); + } + else + backoff_delay(); + +#endif + + // any msgs for us? + + if (unlikely(spu_readchcnt(SPU_RdInMbox))){ + int msg = spu_readch(SPU_RdInMbox); + // printf("spu[%d] mbox_msg: 0x%08x\n", spu_args.spu_idx, msg); + if (MBOX_MSG_OP(msg) == OP_EXIT){ + flush_completion_info(); + return; + } + if (MBOX_MSG_OP(msg) == OP_GET_SPU_BUFSIZE){ + spu_writech(SPU_WrOutIntrMbox, MK_MBOX_MSG(OP_SPU_BUFSIZE, GC_SPU_BUFSIZE_BASE)); + } + } + + // If we've got job completion info for the PPE and we can send a + // message without blocking, do it. + + if (comp_info.ncomplete != 0 && spu_readchcnt(SPU_WrOutIntrMbox) != 0){ + gc_log_write0(GCL_SS_SYS, 0x12); + flush_completion_info(); + } + } +} + + +int +main(unsigned long long spe_id __attribute__((unused)), + unsigned long long argp, + unsigned long long envp __attribute__((unused))) +{ + gc_sys_tag = mfc_tag_reserve(); // allocate a tag for our misc DMA operations + get_tag = mfc_tag_reserve(); + ci_tags = mfc_multi_tag_reserve(2); + put_tags = mfc_multi_tag_reserve(2); + +#if 0 + printf("gc_sys_tag = %d\n", gc_sys_tag); + printf("get_tag = %d\n", get_tag); + printf("ci_tags = %d\n", ci_tags); + printf("put_tags = %d\n", put_tags); +#endif + + // dma the args in + mfc_get(&spu_args, argp, sizeof(spu_args), gc_sys_tag, 0, 0); + mfc_write_tag_mask(1 << gc_sys_tag); // the tag we're interested in + mfc_read_tag_status_all(); // wait for DMA to complete + + // initialize pointer to procedure entry table + gc_proc_def = (gc_proc_def_t *) spu_args.proc_def_ls_addr; + + // initialize logging + _gc_log_init(spu_args.log); + + backoff_init(); // initialize backoff parameters + + main_loop(); + return 0; +} diff --git a/gcell/src/lib/runtime/spu/gc_spu_config.h b/gcell/src/lib/runtime/spu/gc_spu_config.h new file mode 100644 index 000000000..997645e68 --- /dev/null +++ b/gcell/src/lib/runtime/spu/gc_spu_config.h @@ -0,0 +1,33 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_GC_SPU_CONFIG_H +#define INCLUDED_GC_SPU_CONFIG_H + +#include <gc_job_desc.h> + +#define CACHE_LINE_SIZE 128 // in bytes +#define GC_SPU_BUFSIZE_BASE (32 * 1024) // must be multiple of CACHE_LINE_SIZE +#define GC_SPU_BUFSIZE (GC_SPU_BUFSIZE_BASE + MAX_ARGS_EA * CACHE_LINE_SIZE) + +#define NGETBUFS 1 // single buffer job arg gets +#define NPUTBUFS 2 // double buffer job arg puts + +#endif /* INCLUDED_GC_SPU_CONFIG_H */ diff --git a/gcell/src/lib/runtime/spu/gc_spu_jd_queue.c b/gcell/src/lib/runtime/spu/gc_spu_jd_queue.c new file mode 100644 index 000000000..ba4a1b9d2 --- /dev/null +++ b/gcell/src/lib/runtime/spu/gc_spu_jd_queue.c @@ -0,0 +1,103 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "gc_jd_queue.h" +#include "mutex_lock.h" +#include "mutex_unlock.h" + +extern int gc_sys_tag; + +bool +gc_jd_queue_dequeue(gc_eaddr_t q, gc_eaddr_t *item_ea, gc_job_desc_t *item) +{ + gc_jd_queue_t local_q; + + // Before aquiring the lock, see if it's possible that there's + // something in the queue. Checking in this way makes it easier + // for the PPE to insert things, since we're not contending for + // the lock unless there is something in the queue. + + // copy in the queue structure + mfc_get(&local_q, q, sizeof(gc_jd_queue_t), gc_sys_tag, 0, 0); + mfc_write_tag_mask(1 << gc_sys_tag); // the tag we're interested in + mfc_read_tag_status_all(); // wait for DMA to complete + + if (local_q.head == 0){ // empty + return false; + } + + // When we peeked, head was non-zero. Now grab the + // lock and do it for real. + + _mutex_lock(q + offsetof(gc_jd_queue_t, mutex)); + + // copy in the queue structure + mfc_get(&local_q, q, sizeof(gc_jd_queue_t), gc_sys_tag, 0, 0); + mfc_write_tag_mask(1 << gc_sys_tag); // the tag we're interested in + mfc_read_tag_status_all(); // wait for DMA to complete + + if (local_q.head == 0){ // empty + _mutex_unlock(q + offsetof(gc_jd_queue_t, mutex)); + return false; + } + + // copy in job descriptor at head of queue + *item_ea = local_q.head; + mfc_get(item, local_q.head, sizeof(gc_job_desc_t), gc_sys_tag, 0, 0); + mfc_write_tag_mask(1 << gc_sys_tag); // the tag we're interested in + mfc_read_tag_status_all(); // wait for DMA to complete + + local_q.head = item->sys.next; + item->sys.next = 0; + if (local_q.head == 0) // now empty? + local_q.tail = 0; + + + // copy the queue structure back out + mfc_put(&local_q, q, sizeof(gc_jd_queue_t), gc_sys_tag, 0, 0); + mfc_write_tag_mask(1 << gc_sys_tag); // the tag we're interested in + mfc_read_tag_status_all(); // wait for DMA to complete + + // Q: FIXME do we need to order stores in EA or can we just clear the + // local copy of the mutex above and blast it out, removing the need + // for this explicit unlock? + // + // A: Manual says it's better to use an atomic op rather than + // a normal DMA, and that a putlluc is better than a putllc if + // you can use it. + + _mutex_unlock(q + offsetof(gc_jd_queue_t, mutex)); + return true; +} + + +void +gc_jd_queue_getllar(gc_eaddr_t q) +{ + // get reservation that includes the tail of the queue + gc_eaddr_t tail = q + offsetof(gc_jd_queue_t, tail); + + char _tmp[256]; + char *buf = (char *) ALIGN(_tmp, 128); // get cache-aligned buffer + + mfc_getllar(buf, ALIGN128_EA(tail), 0, 0); + spu_readch(MFC_RdAtomicStat); +} diff --git a/gcell/src/lib/runtime/spu/gcell_qa.c b/gcell/src/lib/runtime/spu/gcell_qa.c new file mode 100644 index 000000000..51bf38a6a --- /dev/null +++ b/gcell/src/lib/runtime/spu/gcell_qa.c @@ -0,0 +1,109 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <gc_delay.h> +#include <gc_declare_proc.h> +#include <string.h> + + +#define _UNUSED __attribute__((unused)) + +// FIXME move these out of here; only for QA usage + +static void +qa_nop(const gc_job_direct_args_t *input _UNUSED, + gc_job_direct_args_t *output _UNUSED, + const gc_job_ea_args_t *eaa _UNUSED) +{ +} + +GC_DECLARE_PROC(qa_nop, "qa_nop"); + +static int +sum_shorts(short *p, int nshorts) +{ + int total = 0; + for (int i = 0; i < nshorts; i++) + total += p[i]; + + return total; +} + +static void +qa_sum_shorts(const gc_job_direct_args_t *input _UNUSED, + gc_job_direct_args_t *output, + const gc_job_ea_args_t *eaa) +{ + for (unsigned int i = 0; i < eaa->nargs; i++){ + short *p = eaa->arg[i].ls_addr; + int n = eaa->arg[i].get_size / sizeof(short); + output->arg[i].s32 = sum_shorts(p, n); + //printf("qa_sum_shorts(%p, %d) = %d\n", p, n, output->arg[i].s32); + } +} + +GC_DECLARE_PROC(qa_sum_shorts, "qa_sum_shorts"); + +static void +write_seq(unsigned char *p, int nbytes, int counter) +{ + for (int i = 0; i < nbytes; i++) + p[i] = counter++; +} + +static void +qa_put_seq(const gc_job_direct_args_t *input, + gc_job_direct_args_t *output _UNUSED, + const gc_job_ea_args_t *eaa) +{ + int counter = input->arg[0].s32; + + for (unsigned int i = 0; i < eaa->nargs; i++){ + unsigned char *p = eaa->arg[i].ls_addr; + int n = eaa->arg[i].put_size; + write_seq(p, n, counter); + counter += n; + } +} + +GC_DECLARE_PROC(qa_put_seq, "qa_put_seq"); + +static void +qa_copy(const gc_job_direct_args_t *input _UNUSED, + gc_job_direct_args_t *output, + const gc_job_ea_args_t *eaa) +{ + if (eaa->nargs != 2 + || eaa->arg[0].direction != GCJD_DMA_PUT + || eaa->arg[1].direction != GCJD_DMA_GET){ + output->arg[0].s32 = -1; + return; + } + + output->arg[0].s32 = 0; + unsigned n = eaa->arg[0].put_size; + if (eaa->arg[1].get_size < n) + n = eaa->arg[1].get_size; + + memcpy(eaa->arg[0].ls_addr, eaa->arg[1].ls_addr, n); +} + +GC_DECLARE_PROC(qa_copy, "qa_copy"); diff --git a/gcell/src/lib/runtime/spu/spu_buffers.c b/gcell/src/lib/runtime/spu/spu_buffers.c new file mode 100644 index 000000000..58b405931 --- /dev/null +++ b/gcell/src/lib/runtime/spu/spu_buffers.c @@ -0,0 +1,35 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <spu_buffers.h> +#include <compiler.h> + +static unsigned char _getbuf[NGETBUFS][GC_SPU_BUFSIZE] _AL128; +static unsigned char _putbuf[NPUTBUFS][GC_SPU_BUFSIZE] _AL128; + +unsigned char *_gci_getbuf[NGETBUFS] = { + _getbuf[0] +}; + +unsigned char *_gci_putbuf[NPUTBUFS] = { + _putbuf[0], + _putbuf[1] +}; diff --git a/gcell/src/lib/runtime/spu/spu_buffers.h b/gcell/src/lib/runtime/spu/spu_buffers.h new file mode 100644 index 000000000..24811dc38 --- /dev/null +++ b/gcell/src/lib/runtime/spu/spu_buffers.h @@ -0,0 +1,32 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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 3, or (at your option) + * any later version. + * + * GNU Radio 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_SPU_BUFFERS_H +#define INCLUDED_SPU_BUFFERS_H + +#include "gc_spu_config.h" + +//! pointer to input buffer +extern unsigned char *_gci_getbuf[NGETBUFS]; + +//! pointers to output buffers +extern unsigned char *_gci_putbuf[NPUTBUFS]; + +#endif /* INCLUDED_SPU_BUFFERS_H */ diff --git a/gcell/src/lib/spu/Makefile.am b/gcell/src/lib/spu/Makefile.am new file mode 100644 index 000000000..fac057cd5 --- /dev/null +++ b/gcell/src/lib/spu/Makefile.am @@ -0,0 +1,103 @@ +# +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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 3, or (at your option) +# any later version. +# +# GNU Radio 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# + +# We're building a single .a file from files in several +# subdirectories. We use the "single Makefile, multiple subdirectory" +# automake alternative. We're doing this because we're faking out +# automake and getting it to build for 2 architectures at the same +# time, the PPE (powerpc64) and the SPE. The easiest way to handle +# the SPE was to just build a static library using automake's built in +# rules, since trying to get libtool to handle two architectures in +# the same tree seemed untenable. + +include $(top_srcdir)/Makefile.common.spu + +IBM_SPU_SYNC_INCLUDES = -I$(top_srcdir)/gcell/src/ibm/sync/spu_source +AM_CPPFLAGS = $(GCELL_SPU_INCLUDES) $(IBM_SPU_SYNC_INCLUDES) + +lib_LIBRARIES = libgcell_spu.a + +# ---------------------------------------------------------------- +# files in the lib/runtime/spu directory + +runtime_srcdir = $(srcdir)/../runtime/spu + +runtime_spu_sources = \ + $(runtime_srcdir)/gc_delay.c \ + $(runtime_srcdir)/gc_spu_jd_queue.c \ + $(runtime_srcdir)/spu_buffers.c \ + $(runtime_srcdir)/gc_logging.c \ + $(runtime_srcdir)/gc_main.c + +runtime_spu_headers = + +runtime_spu_noinst_headers = \ + $(runtime_srcdir)/gc_spu_config.h \ + $(runtime_srcdir)/spu_buffers.h + +# ---------------------------------------------------------------- +# files in the lib/general/spu directory + +general_srcdir = $(srcdir)/../general/spu + +general_spu_sources = + +general_spu_headers = + +general_spu_noinst_headers = + + +# ---------------------------------------------------------------- +# files in the lib/procs/spu directory + +procs_srcdir = $(srcdir)/../proc/spu + +procs_spu_sources = + +procs_spu_headers = + +procs_spu_noinst_headers = + +# ---------------------------------------------------------------- +# build the library from the files in the three directories + +libgcell_spu_a_SOURCES = \ + $(runtime_spu_sources) \ + $(general_spu_sources) \ + $(procs_spu_sources) + +gcellspuinclude_HEADERS = \ + $(runtime_spu_headers) \ + $(general_spu_headers) \ + $(procs_spu_headers) + +noinst_HEADERS = \ + $(runtime_spu_noinst_headers) \ + $(general_spu_noinst_headers) \ + $(procs_spu_noinst_headers) + +# ---------------------------------------------------------------- +# SPU executable containing QA code + +noinst_PROGRAMS = \ + gcell_qa + +gcell_qa_SOURCES = $(runtime_srcdir)/gcell_qa.c +gcell_qa_LDADD = libgcell_spu.a |