Gs-commits
Threads by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
April 2009
- 4 participants
- 142 discussions
r467 - in branches/code/dense-1: src/cmpi src/cmpi-cp src/include test/adts test/cmpi-cp test/driver
by wozniak@mcs.anl.gov 30 Apr '09
by wozniak@mcs.anl.gov 30 Apr '09
30 Apr '09
Author: wozniak
Date: 2009-04-30 17:52:35 -0500 (Thu, 30 Apr 2009)
New Revision: 467
Added:
branches/code/dense-1/src/cmpi-cp/cmpi-cp.c
branches/code/dense-1/src/cmpi-cp/module.mk.in
branches/code/dense-1/src/cmpi/accessor.c
branches/code/dense-1/src/include/accessor.h
branches/code/dense-1/src/include/cmpi-cp.h
branches/code/dense-1/test/adts/test06.c
branches/code/dense-1/test/cmpi-cp/About.txt
branches/code/dense-1/test/cmpi-cp/datafile01.txt
branches/code/dense-1/test/cmpi-cp/test01.zsh
branches/code/dense-1/test/cmpi-cp/test02.zsh
branches/code/dense-1/test/driver/About.txt
branches/code/dense-1/test/driver/module.mk.in
branches/code/dense-1/test/driver/test01.c
branches/code/dense-1/test/driver/test01.zsh
branches/code/dense-1/test/driver/test02.c
branches/code/dense-1/test/driver/test02.zsh
branches/code/dense-1/test/driver/test03.c
branches/code/dense-1/test/driver/test_driver_fifo.c
branches/code/dense-1/test/driver/test_helpers.c
branches/code/dense-1/test/driver/test_helpers.h
Log:
New files for cmpi-cp and related tests.
Added: branches/code/dense-1/src/cmpi/accessor.c
===================================================================
--- branches/code/dense-1/src/cmpi/accessor.c (rev 0)
+++ branches/code/dense-1/src/cmpi/accessor.c 2009-04-30 22:52:35 UTC (rev 467)
@@ -0,0 +1,26 @@
+
+#include <accessor.h>
+
+/**
+ @return True iff successfully access to fifos is made.
+*/
+bool
+driver_access_fifo()
+{
+ char fifo_in[20] = "/tmp/cmpi.fifo.in";
+ char fifo_out[20] = "/tmp/cmpi.fifo.out";
+
+ to_cmpi = fopen(fifo_in, "w");
+ if (to_cmpi == NULL)
+ {
+ printf("Could not open: %s \n", fifo_in);
+ return false;
+ }
+ from_cmpi = fopen(fifo_out, "r");
+ if (from_cmpi == NULL)
+ {
+ printf("Could not open: %s \n", fifo_out);
+ return false;
+ }
+ return true;
+}
Added: branches/code/dense-1/src/cmpi-cp/cmpi-cp.c
===================================================================
--- branches/code/dense-1/src/cmpi-cp/cmpi-cp.c (rev 0)
+++ branches/code/dense-1/src/cmpi-cp/cmpi-cp.c 2009-04-30 22:52:35 UTC (rev 467)
@@ -0,0 +1,262 @@
+
+#include <cmpi-cp.h>
+
+typedef enum
+{
+ CMPI_CP_KEY,
+ CMPI_CP_FILE,
+ CMPI_CP_STREAM,
+ CMPI_CP_TYPE_ERROR,
+} CMPI_CP_TYPE;
+
+char* target1;
+char* target2;
+
+int value_size;
+
+void printhelp(void);
+
+#define debug(x) x
+
+void
+cmpi_cp_args(int argc, char* argv[])
+{
+ if (argc == 1)
+ {
+ printhelp();
+ exit(EXIT_FAILURE);
+ }
+ target1 = argv[1];
+ target2 = argv[2];
+}
+
+void
+printhelp()
+{
+ printf("usage: cmpi [OPTION] target1 target2 \n");
+ printf(" each target is a file path \n");
+ printf(" or a DHT key formatted as dht://<key> \n\n");
+ printf("options: \n");
+ printf(" -h print this message \n");
+ printf(" -v show version information \n");
+ printf(" -c set chunk size \n");
+}
+
+/**
+ Determine the type of this target, file or key.
+*/
+CMPI_CP_TYPE
+cmpi_cp_extract_type(char* target, char* value)
+{
+ CMPI_CP_TYPE result;
+ if (strstr(target, "dht://"))
+ {
+ strcpy(value, target+6);
+ result = CMPI_CP_KEY;
+ debug(printf("%s is key %s\n", target, value));
+ }
+ else if (strstr(target, "-") && strlen(target) == 1)
+ {
+ strcpy(value, target);
+ result = CMPI_CP_STREAM;
+ debug(printf("%s is a stream\n", value));
+ }
+ else
+ {
+ strcpy(value, target);
+ result = CMPI_CP_FILE;
+ debug(printf("%s is a file\n", value));
+ }
+ return result;
+}
+
+CMPI_RETURN
+cmpi_cp_put(FILE* file, char* object)
+{
+ debug(printf("cmpi_cp_put()\n"));
+ char key[CMPI_KEY_LENGTH+10];
+ char data[value_size+1];
+ int count = 0;
+ while (! feof(file))
+ {
+ sprintf(key, "%s[%i]", object, count++);
+ int total = 0;
+ while (!feof(file) &&
+ total < value_size)
+ {
+ int chunk = value_size-total;
+ printf("reading...\n");
+ int actual = fread(data+total, 1, chunk, file);
+ data[total+actual] = '\0';
+ printf("read: %i\n", actual);
+ printf("data: %s\n", data);
+
+ total += actual;
+ sleep(1);
+ }
+ fprintf(to_cmpi, "put %s %i\n", key, total);
+ fflush(to_cmpi);
+ fprintf(to_cmpi, "%s", data);
+ printf("cmpi_cp_put data: %s\n", data);
+ fflush(to_cmpi);
+ }
+
+ sprintf(data, "DHT: %i", count);
+ fprintf(to_cmpi, "put %s %i\n", object, (int) strlen(data));
+ fflush(to_cmpi);
+ fprintf(to_cmpi, "%s", data);
+ fflush(to_cmpi);
+
+ char result[32];
+ fscanf(from_cmpi, "%s", result);
+
+ if (strncmp(result, "ok", 2) != 0)
+ return CMPI_ERROR_UNKNOWN;
+
+ return CMPI_SUCCESS;
+}
+
+CMPI_RETURN
+cmpi_cp_get(char* object, FILE* file)
+{
+ debug(printf("cmpi_cp_get(%s)\n", object));
+ char data[value_size+1];
+ int count, c;
+ int length;
+ int value_size;
+ int total;
+
+ fprintf(to_cmpi, "get %s\n", object);
+ fflush(to_cmpi);
+ fscanf(from_cmpi, "length: %i\n", &length);
+
+ printf("length: %i\n", length);
+
+ value_size = count;
+ total = 0;
+ while (total < value_size)
+ {
+ int chunk = value_size-total;
+ int actual = fread(data+total, 1, chunk, from_cmpi);
+ data[total+actual] = '\0';
+ printf("read: %i\n", actual);
+ printf("data: %s\n", data);
+ total += actual;
+ sleep(2);
+ }
+ sscanf(data, "DHT: %i", &count);
+
+ fscanf(from_cmpi, "DHT: %i", &count);
+ printf("count: %i\n", count);
+
+ for (c = 0; c < count; c++)
+ {
+
+ fprintf(to_cmpi, "get %s[%i]\n", object, c);
+ fflush(to_cmpi);
+ fscanf(from_cmpi, "%i\n", &value_size);
+
+ total = 0;
+ while (total < value_size)
+ {
+ int chunk = value_size-total;
+ int actual = fread(data+total, 1, chunk, from_cmpi);
+ data[total+actual] = '\0';
+ printf("read: %i\n", actual);
+ printf("data: %s\n", data);
+ total += actual;
+ sleep(2);
+ }
+ total = 0;
+ while (total < value_size)
+ {
+ int chunk = value_size-total;
+ int actual = fwrite(data+total, 1, chunk, file);
+ data[total+actual] = '\0';
+ printf("wrote: %i\n", actual);
+ total += actual;
+ sleep(2);
+ }
+ }
+
+ return CMPI_SUCCESS;
+}
+
+void
+bad_file(char* filename)
+{
+ printf("Could not open: %s\n", filename);
+ exit(EXIT_FAILURE);
+}
+
+void
+cmpi_cp_case(CMPI_CP_TYPE type1, char* object1,
+ CMPI_CP_TYPE type2, char* object2)
+{
+ if (type1 == CMPI_CP_FILE &&
+ type2 == CMPI_CP_KEY)
+ {
+ // FILE -> DHT
+ FILE* file = fopen(object1, "r");
+ if (!file)
+ bad_file(object1);
+ cmpi_cp_put(file, object2);
+ fclose(file);
+ }
+ else if (type1 == CMPI_CP_KEY &&
+ type2 == CMPI_CP_FILE)
+ {
+ // DHT -> FILE
+ FILE* file = fopen(object2, "w");
+ if (!file)
+ bad_file(object2);
+ cmpi_cp_get(object1, file);
+ fclose(file);
+ }
+ else if (type1 == CMPI_CP_KEY &&
+ type2 == CMPI_CP_KEY)
+ {
+ // DHT -> DHT
+ }
+ else if (type1 == CMPI_CP_STREAM &&
+ type2 == CMPI_CP_FILE)
+ {
+ // STREAM -> DHT
+ }
+ else if (type1 == CMPI_CP_FILE &&
+ type2 == CMPI_CP_STREAM)
+ {
+ // DHT -> STREAM
+ }
+}
+
+int
+main(int argc, char* argv[])
+{
+ CMPI_CP_TYPE target1_type;
+ CMPI_CP_TYPE target2_type;
+
+ char object1[CMPI_KEY_LENGTH+10];
+ char object2[CMPI_KEY_LENGTH+10];
+
+ // value_size = CMPI_CP_CHUNK;
+ value_size = 4;
+
+ cmpi_cp_args(argc, argv);
+ target1_type = cmpi_cp_extract_type(target1, object1);
+ target2_type = cmpi_cp_extract_type(target2, object2);
+
+ if (target1_type == CMPI_CP_FILE &&
+ target2_type == CMPI_CP_FILE)
+ {
+ printf("cmpi-cp: given two files!\n");
+ exit(EXIT_FAILURE);
+ }
+
+ driver_access_fifo();
+
+ cmpi_cp_case(target1_type, object1, target2_type, object2);
+
+
+ return EXIT_SUCCESS;
+}
Added: branches/code/dense-1/src/cmpi-cp/module.mk.in
===================================================================
--- branches/code/dense-1/src/cmpi-cp/module.mk.in (rev 0)
+++ branches/code/dense-1/src/cmpi-cp/module.mk.in 2009-04-30 22:52:35 UTC (rev 467)
@@ -0,0 +1,15 @@
+
+# CMPI-CP is not an MPI program
+
+DIR = src/cmpi-cp
+
+CMPI_PROGS += bin/cmpi-cp
+CMPI_SRC += $(DIR)/cmpi-cp.c
+
+CMPI_CP_OBJS = src/cmpi/accessor.o
+
+bin/cmpi-cp: src/cmpi-cp/cmpi-cp.o $(CMPI_CP_OBJS)
+ $(Q) " MKDIR bin "
+ $(E)mkdir -p bin
+ $(Q) " CC $(@) "
+ $(E)$(CC) $(<) $(CMPI_CP_OBJS) -o $(@)
Added: branches/code/dense-1/src/include/accessor.h
===================================================================
--- branches/code/dense-1/src/include/accessor.h (rev 0)
+++ branches/code/dense-1/src/include/accessor.h 2009-04-30 22:52:35 UTC (rev 467)
@@ -0,0 +1,9 @@
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+FILE* to_cmpi;
+FILE* from_cmpi;
+
+bool driver_access_fifo(void);
Added: branches/code/dense-1/src/include/cmpi-cp.h
===================================================================
--- branches/code/dense-1/src/include/cmpi-cp.h (rev 0)
+++ branches/code/dense-1/src/include/cmpi-cp.h 2009-04-30 22:52:35 UTC (rev 467)
@@ -0,0 +1,7 @@
+
+#include <node.h>
+#include <accessor.h>
+
+// #define CMPI_CP_CHUNK CMPI_VALUE_LENGTH
+
+#define CMPI_CP_CHUNK 8
Added: branches/code/dense-1/test/adts/test06.c
===================================================================
--- branches/code/dense-1/test/adts/test06.c (rev 0)
+++ branches/code/dense-1/test/adts/test06.c 2009-04-30 22:52:35 UTC (rev 467)
@@ -0,0 +1,28 @@
+
+/**
+ * Test list functionality.
+ * */
+
+#include <list.h>
+
+int
+main(int argc, char* argv[])
+{
+ struct list* L;
+
+ MPI_Init(&argc, &argv);
+ whoami();
+
+ L = list_parse("jkl iop l");
+
+ list_printf("%s", L);
+ fflush(stdout);
+ list_destroy(L);
+
+ L = list_parse(" jkl iop l ");
+ list_printf("%s", L);
+ list_destroy(L);
+
+ MPI_Finalize();
+ return 0;
+}
Added: branches/code/dense-1/test/cmpi-cp/About.txt
===================================================================
--- branches/code/dense-1/test/cmpi-cp/About.txt (rev 0)
+++ branches/code/dense-1/test/cmpi-cp/About.txt 2009-04-30 22:52:35 UTC (rev 467)
@@ -0,0 +1,4 @@
+
+test01: Copy datafile01.txt into the DHT and shut it down.
+test02: Copy datafile01.txt into the DHT,
+ extract it to datafile01.out, and shut it down.
Added: branches/code/dense-1/test/cmpi-cp/datafile01.txt
===================================================================
--- branches/code/dense-1/test/cmpi-cp/datafile01.txt (rev 0)
+++ branches/code/dense-1/test/cmpi-cp/datafile01.txt 2009-04-30 22:52:35 UTC (rev 467)
@@ -0,0 +1 @@
+hellowhoisthis
Added: branches/code/dense-1/test/cmpi-cp/test01.zsh
===================================================================
--- branches/code/dense-1/test/cmpi-cp/test01.zsh (rev 0)
+++ branches/code/dense-1/test/cmpi-cp/test01.zsh 2009-04-30 22:52:35 UTC (rev 467)
@@ -0,0 +1,22 @@
+#!/bin/zsh
+
+make -j D=1 bin/cmpi-cp test/driver/test_driver.x test/driver/test02.x
+[[ $? != 0 ]] && exit 1
+sleep 2
+
+mpiexec -n 5 test/driver/test_driver.x -n 4 -s 1 >& driver.out &
+DRIVER_PID=${!}
+sleep 5
+
+print
+print "CMPI-CP..."
+bin/cmpi-cp test/cmpi-cp/datafile01.txt dht://datafile01.txt
+print "CMPI-CP DONE"
+
+sleep 10
+
+print
+print "Killing driver (test/driver/test02.x)..."
+test/driver/test02.x
+
+wait
Property changes on: branches/code/dense-1/test/cmpi-cp/test01.zsh
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/code/dense-1/test/cmpi-cp/test02.zsh
===================================================================
--- branches/code/dense-1/test/cmpi-cp/test02.zsh (rev 0)
+++ branches/code/dense-1/test/cmpi-cp/test02.zsh 2009-04-30 22:52:35 UTC (rev 467)
@@ -0,0 +1,27 @@
+#!/bin/zsh
+
+make -j D=1 bin/cmpi-cp test/driver/test_driver.x test/driver/test02.x
+[[ $? != 0 ]] && exit 1
+sleep 2
+
+mpiexec -n 5 test/driver/test_driver.x -n 4 -s 1 >& driver.out &
+DRIVER_PID=${!}
+sleep 2
+
+print
+print "CMPI-CP..."
+bin/cmpi-cp test/cmpi-cp/datafile01.txt dht://datafile01.txt
+print "CMPI-CP DONE"
+
+sleep 5
+
+bin/cmpi-cp dht://datafile01.txt test/cmpi-cp/datafile01.out
+print "CMPI-CP DONE"
+
+sleep 5
+
+print
+print "Killing driver (test/driver/test02.x)..."
+test/driver/test02.x
+
+wait
Property changes on: branches/code/dense-1/test/cmpi-cp/test02.zsh
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/code/dense-1/test/driver/About.txt
===================================================================
--- branches/code/dense-1/test/driver/About.txt (rev 0)
+++ branches/code/dense-1/test/driver/About.txt 2009-04-30 22:52:35 UTC (rev 467)
@@ -0,0 +1,9 @@
+
+test_driver: Start up a DHT with a driver process.
+
+test01.x: Issue a "sleep 3" command to the driver.
+test02.x: Issue a "quit" to the driver.
+test03.x: Insert data via the driver.
+
+test01.zsh: Call test01.x and test02.x
+test02.zsh: Call test03.x and test02.x
Added: branches/code/dense-1/test/driver/module.mk.in
===================================================================
--- branches/code/dense-1/test/driver/module.mk.in (rev 0)
+++ branches/code/dense-1/test/driver/module.mk.in 2009-04-30 22:52:35 UTC (rev 467)
@@ -0,0 +1,16 @@
+
+TEST_DRIVER_SRC += $(shell cd @SRC_ABSOLUTE_TOP@; find test/driver -name "*.c" ! -name test_helpers.c)
+TEST_SRC += $(TEST_DRIVER_SRC)
+TEST_HELPER_SRC += test/driver/test_helpers.c
+
+DRIVER = test/driver/test_driver.x
+
+DRIVER_IMPL = test/driver/test_driver_fifo.o
+
+test/driver/test%.x: test/driver/test%.o $(DRIVER)
+ $(Q) " MPICC $(@) "
+ $(E)$(MPICC) $(MPE) $(<) $(CMPI) $(LIBS) -o $(@)
+
+$(DRIVER): $(DRIVER_IMPL) test/driver/test_helpers.o src/cmpi/node.o $(CMPI)
+ $(E)$(MPICC) $(MPE) $(<) test/driver/test_helpers.o src/cmpi/node.o \
+ $(CMPI) $(LIBS) -o $(@)
Added: branches/code/dense-1/test/driver/test01.c
===================================================================
--- branches/code/dense-1/test/driver/test01.c (rev 0)
+++ branches/code/dense-1/test/driver/test01.c 2009-04-30 22:52:35 UTC (rev 467)
@@ -0,0 +1,21 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <accessor.h>
+
+int
+main(int argc, char* argv[])
+{
+ driver_access_fifo();
+
+ fprintf(to_cmpi, "sleep 3\n");
+ fflush(to_cmpi);
+ char output[30];
+ fscanf(from_cmpi, "output: %s", output);
+
+ printf("%s\n", output);
+
+ return 0;
+}
+
Added: branches/code/dense-1/test/driver/test01.zsh
===================================================================
--- branches/code/dense-1/test/driver/test01.zsh (rev 0)
+++ branches/code/dense-1/test/driver/test01.zsh 2009-04-30 22:52:35 UTC (rev 467)
@@ -0,0 +1,18 @@
+#!/bin/zsh
+
+make -j 3 D=1 test/driver/test01.x test/driver/test02.x \
+ test/driver/test_driver.x
+
+mpiexec -n 5 test/driver/test_driver.x -n 4 &
+DRIVER_PID=${!}
+
+sleep 5
+
+print "Launching tool 01..."
+test/driver/test01.x
+
+print "Launching tool 02..."
+test/driver/test02.x
+
+wait
+
Property changes on: branches/code/dense-1/test/driver/test01.zsh
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/code/dense-1/test/driver/test02.c
===================================================================
--- branches/code/dense-1/test/driver/test02.c (rev 0)
+++ branches/code/dense-1/test/driver/test02.c 2009-04-30 22:52:35 UTC (rev 467)
@@ -0,0 +1,20 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <accessor.h>
+
+int
+main(int argc, char* argv[])
+{
+ driver_access_fifo();
+
+ fprintf(to_cmpi, "quit\n");
+ fflush(to_cmpi);
+ char output[30];
+ fscanf(from_cmpi, "output: %s", output);
+
+ printf("%s\n", output);
+
+ return 0;
+}
Added: branches/code/dense-1/test/driver/test02.zsh
===================================================================
--- branches/code/dense-1/test/driver/test02.zsh (rev 0)
+++ branches/code/dense-1/test/driver/test02.zsh 2009-04-30 22:52:35 UTC (rev 467)
@@ -0,0 +1,20 @@
+#!/bin/zsh
+
+make -j 3 D=1 test/driver/test02.x test/driver/test03.x \
+ test/driver/test_driver.x
+[[ $? != 0 ]] && exit
+sleep 1
+
+mpiexec -n 5 test/driver/test_driver.x -n 4 &
+DRIVER_PID=${!}
+
+sleep 5
+
+print "Launching tool 03..."
+test/driver/test03.x
+
+print "Launching tool 02..."
+test/driver/test02.x
+
+wait
+
Property changes on: branches/code/dense-1/test/driver/test02.zsh
___________________________________________________________________
Name: svn:executable
+ *
Added: branches/code/dense-1/test/driver/test03.c
===================================================================
--- branches/code/dense-1/test/driver/test03.c (rev 0)
+++ branches/code/dense-1/test/driver/test03.c 2009-04-30 22:52:35 UTC (rev 467)
@@ -0,0 +1,25 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <accessor.h>
+
+int
+main(int argc, char* argv[])
+{
+ driver_access_fifo();
+
+ char data[30] = "hello does this work";
+
+ fprintf(to_cmpi, "put key1 %i\n", (int) strlen(data));
+ fprintf(to_cmpi, "%s", data);
+ fflush(to_cmpi);
+
+ char output[30];
+ fscanf(from_cmpi, "output: %s", output);
+
+ printf("%s\n", output);
+
+ return 0;
+}
Added: branches/code/dense-1/test/driver/test_driver_fifo.c
===================================================================
--- branches/code/dense-1/test/driver/test_driver_fifo.c (rev 0)
+++ branches/code/dense-1/test/driver/test_driver_fifo.c 2009-04-30 22:52:35 UTC (rev 467)
@@ -0,0 +1,24 @@
+
+#include <node.h>
+#include <driver.h>
+
+#include "test_helpers.h"
+
+void
+cmpi_client_code()
+{
+ wait_for_notification();
+ notify_next();
+
+ NOTE("PROCEEDING...");
+
+ cmpi_driver* driver = driver_create();
+
+ while (! driver->quitting)
+ {
+ driver_setup_fifo(driver);
+ driver_process(driver);
+ }
+
+ NOTE("QUITTING");
+}
Added: branches/code/dense-1/test/driver/test_helpers.c
===================================================================
--- branches/code/dense-1/test/driver/test_helpers.c (rev 0)
+++ branches/code/dense-1/test/driver/test_helpers.c 2009-04-30 22:52:35 UTC (rev 467)
@@ -0,0 +1,52 @@
+
+// #include <stdio.h>
+
+#include "test_helpers.h"
+
+/**
+ Print debugging header using machine-specific information.
+*/
+void
+print_header(void)
+{
+ // Are we a SLURM job?
+ char* slurm_id = getenv("SLURM_JOBID");
+ if (slurm_id)
+ printf("SLURM_JOBID: %s\n", slurm_id);
+}
+
+char*
+useless_data(int size)
+{
+ int i;
+ char* s = malloc(size*sizeof(char));
+ for (i = 0; i < size-1; i++)
+ s[i] = 'a' + rand_lt(26);
+ s[size-1] = '\0';
+ return s;
+}
+
+void
+wait_for_notification(void)
+{
+ int tmp;
+ MPI_Status status;
+ MPI_Recv(&tmp, 1, MPI_INT,
+ MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
+ assert(tmp == -2);
+}
+
+void
+notify_next(void)
+{
+ if (mpi_rank < mpi_size-1)
+ {
+ int msg = -2;
+ MPI_Send(&msg, 1, MPI_INT,
+ mpi_rank+1, 0, MPI_COMM_WORLD);
+ }
+ else
+ {
+ NOTE("NOTIFICATION_FINALIZED");
+ }
+}
Added: branches/code/dense-1/test/driver/test_helpers.h
===================================================================
--- branches/code/dense-1/test/driver/test_helpers.h (rev 0)
+++ branches/code/dense-1/test/driver/test_helpers.h 2009-04-30 22:52:35 UTC (rev 467)
@@ -0,0 +1,20 @@
+
+// #include <stdio.h>
+
+#ifndef TEST_HELPERS_H
+#define TEST_HELPERS_H
+
+#include <node.h>
+#include <gossip.h>
+
+/**
+ Print debugging header using machine-specific information.
+*/
+void print_header(void);
+
+char* useless_data(int size);
+
+void wait_for_notification(void);
+void notify_next(void);
+
+#endif
1
0
r466 - in branches/code/dense-1: . src/adts src/cmpi src/dense-1 src/include src/mpirpc-2 test/adts test/cmpi test/disksim test/gossip test/mpi_tools test/mpirpc-1 test/mpirpc-2 test/paper1
by wozniak@mcs.anl.gov 30 Apr '09
by wozniak@mcs.anl.gov 30 Apr '09
30 Apr '09
Author: wozniak
Date: 2009-04-30 17:49:07 -0500 (Thu, 30 Apr 2009)
New Revision: 466
Modified:
branches/code/dense-1/Makefile.in
branches/code/dense-1/configure.ac
branches/code/dense-1/src/adts/dpkm_list.c
branches/code/dense-1/src/adts/lru_table.c
branches/code/dense-1/src/cmpi/cmpi.c
branches/code/dense-1/src/cmpi/cmpi_disk_void.c
branches/code/dense-1/src/cmpi/driver.c
branches/code/dense-1/src/cmpi/module.mk.in
branches/code/dense-1/src/cmpi/node.c
branches/code/dense-1/src/dense-1/cmpi_dense.c
branches/code/dense-1/src/dense-1/dense.c
branches/code/dense-1/src/include/cmpi.h
branches/code/dense-1/src/include/cmpi_disk.h
branches/code/dense-1/src/include/dense-1.h
branches/code/dense-1/src/include/dpkm_list.h
branches/code/dense-1/src/include/keyvalue.h
branches/code/dense-1/src/include/lru_table.h
branches/code/dense-1/src/include/mpirpc-2.h
branches/code/dense-1/src/mpirpc-2/mpirpc.c
branches/code/dense-1/test/adts/module.mk.in
branches/code/dense-1/test/cmpi/module.mk.in
branches/code/dense-1/test/disksim/module.mk.in
branches/code/dense-1/test/gossip/module.mk.in
branches/code/dense-1/test/mpi_tools/module.mk.in
branches/code/dense-1/test/mpirpc-1/module.mk.in
branches/code/dense-1/test/mpirpc-2/module.mk.in
branches/code/dense-1/test/mpirpc-2/test01.c
branches/code/dense-1/test/paper1/module.mk.in
Log:
Saving position to wfh.
Modified: branches/code/dense-1/Makefile.in
===================================================================
--- branches/code/dense-1/Makefile.in 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/Makefile.in 2009-04-30 22:49:07 UTC (rev 466)
@@ -339,12 +339,14 @@
$(E)echo USE_TABLE_KDA_2A: @USE_TABLE_KDA_2A@
$(E)echo USE_TABLE_KDA_2B: @USE_TABLE_KDA_2B@
$(E)echo USE_TABLE_DENSE_1: @USE_TABLE_DENSE_1@
- $(E)echo TEST_CMPI_SRCS: $(TEST_CMPI_SRCS)
- $(E)echo TEST_DISKSIM_SRCS: $(TEST_DISKSIM_SRCS)
- $(E)echo TEST_MPIRPC_SRCS: $(TEST_MPIRPC_SRCS)
- $(E)echo TEST_PAPER1_SRCS: $(TEST_PAPER1_SRCS)
- $(E)echo TEST_SRCS: $(TEST_SRCS)
- $(E)echo TEST_HELPER_SRCS: $(TEST_HELPER_SRCS)
+ $(E)echo CMPI_SRC: $(CMPI_OBJS)
+ $(E)echo CMPI_OBJS: $(CMPI_OBJS)
+ $(E)echo TEST_CMPI_SRC: $(TEST_CMPI_SRC)
+ $(E)echo TEST_DISKSIM_SRC: $(TEST_DISKSIM_SRC)
+ $(E)echo TEST_MPIRPC_SRC: $(TEST_MPIRPC_SRC)
+ $(E)echo TEST_PAPER1_SRC: $(TEST_PAPER1_SRC)
+ $(E)echo TEST_SRC: $(TEST_SRC)
+ $(E)echo TEST_HELPER_SRC: $(TEST_HELPER_SRC)
$(E)echo TEST_PROGS: $(TEST_PROGS)
$(E)echo TEST_DEPS: $(TEST_DEPS)
$(Q) " "
@@ -357,12 +359,12 @@
include module.mk
include $(MODULES)
-TEST_OBJS += $(patsubst %.c, %.o, $(TEST_SRCS))
-TEST_PROGS += $(patsubst %.c, %.x, $(TEST_SRCS))
-TEST_OUTPUT += $(patsubst %.c, %.out, $(TEST_SRCS))
-TEST_DEPS += $(patsubst %.c, %.d, $(TEST_SRCS))
-TEST_HELPER_OBJS += $(patsubst %.c, %.o, $(TEST_HELPER_SRCS))
-TEST_DEPS += $(patsubst %.c, %.d, $(TEST_HELPER_SRCS))
+TEST_OBJS += $(patsubst %.c, %.o, $(TEST_SRC))
+TEST_PROGS += $(patsubst %.c, %.x, $(TEST_SRC))
+TEST_OUTPUT += $(patsubst %.c, %.out, $(TEST_SRC))
+TEST_DEPS += $(patsubst %.c, %.d, $(TEST_SRC))
+TEST_HELPER_OBJS += $(patsubst %.c, %.o, $(TEST_HELPER_SRC))
+TEST_DEPS += $(patsubst %.c, %.d, $(TEST_HELPER_SRC))
################################################################
# Derived file lists
@@ -384,7 +386,7 @@
TABLE_OBJS := $(KDA_OBJS) $(DENSE_OBJS)
CMPI_OBJS := $(patsubst %.c,%.o, $(filter %.c,$(CMPI_SRC)))
CMPI_OBJS += $(TABLE_OBJS) $(MPIRPC_OBJS) $(DISKSIM_OBJS)
-CMPI_PICS += src/cmpi/cmpi-io.po
+# CMPI_PICS += src/cmpi/cmpi-io.po
CMPI_DEPS := $(patsubst %.o,%.d,$(CMPI_OBJS))
Modified: branches/code/dense-1/configure.ac
===================================================================
--- branches/code/dense-1/configure.ac 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/configure.ac 2009-04-30 22:49:07 UTC (rev 466)
@@ -865,6 +865,7 @@
src/common/gossip/module.mk
src/adts/module.mk
src/cmpi/module.mk
+src/cmpi-cp/module.mk
src/mpi_tools/module.mk
src/mpirpc-1/module.mk
src/mpirpc-2/module.mk
Modified: branches/code/dense-1/src/adts/dpkm_list.c
===================================================================
--- branches/code/dense-1/src/adts/dpkm_list.c 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/src/adts/dpkm_list.c 2009-04-30 22:49:07 UTC (rev 466)
@@ -5,7 +5,7 @@
dpkm_list_create(int limit)
{
// SHOW_FI(limit);
- struct dpkm_list* new_dpkm_list = MALLOC(sizeof(struct dpkm_list));
+ struct dpkm_list* new_dpkm_list = malloc(sizeof(struct dpkm_list));
if (! new_dpkm_list)
return NULL;
new_dpkm_list->head = NULL;
@@ -21,17 +21,18 @@
@return The new dpkm_list_item.
*/
struct dpkm_list_item*
-dpkm_list_add(struct dpkm_list* target, char* key, void* data)
+dpkm_list_add(struct dpkm_list* target, char* key, void* data, int length)
{
struct dpkm_list_item* result = NULL;
- struct dpkm_list_item* new_item = MALLOC(sizeof(struct dpkm_list_item));
+ struct dpkm_list_item* new_item = malloc(sizeof(struct dpkm_list_item));
if (! new_item)
return NULL;
- new_item->key = key;
- new_item->data = data;
- new_item->next = NULL;
+ new_item->key = key;
+ new_item->data = data;
+ new_item->next = NULL;
+ new_item->length = length;
if (target->size == 0)
{
Modified: branches/code/dense-1/src/adts/lru_table.c
===================================================================
--- branches/code/dense-1/src/adts/lru_table.c 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/src/adts/lru_table.c 2009-04-30 22:49:07 UTC (rev 466)
@@ -74,7 +74,7 @@
that was LRU and selected as a victim.
*/
struct keyvalue*
-lru_table_add(struct lru_table* table, char* key, char* data)
+lru_table_add(struct lru_table* table, char* key, char* data, int length)
{
// NOTE_F;
@@ -84,10 +84,10 @@
// printf("%s -> %i \n", key, index);
- dpkm_list_add(table->array[index], key, data);
+ dpkm_list_add(table->array[index], key, data, length);
struct dpkm_list_item* victim =
- dpkm_list_add(table->lru, key, data);
+ dpkm_list_add(table->lru, key, data, length);
table->array[index]->tail->ptr = table->lru->tail;
table->lru->tail->ptr = table->array[index]->tail;
@@ -104,9 +104,10 @@
// NOTE_S("VICTIM: ", ((struct dpkm_list_item*)victim->ptr)->key);
dpkm_list_excise(table->array[victim_index], victim->ptr);
result = (struct keyvalue*) MALLOC(sizeof(struct keyvalue));
- result->key = victim->key;
+ result->key = victim->key;
// SHOW_S(result->key);
- result->data = victim->data;
+ result->data = victim->data;
+ result->length = victim->length;
FREE(victim->ptr);
FREE(victim);
}
@@ -116,20 +117,27 @@
/**
Search the table and touch the key/data pair
- to prevent vicitimization.
+ to prevent vicitimization.
+ All data in result must be freed.
@return The data item.
*/
-char*
+struct keyvalue*
lru_table_search(struct lru_table* table, char* key)
{
struct dpkm_list_item* item = NULL;
int index = hash_string(key, table->capacity);
+ struct keyvalue* result;
item = dpkm_list_search(table->array[index], key);
if (item)
{
dpkm_list_pushback(table->lru, item->ptr);
- return item->data;
+ result = malloc(sizeof(keyvalue));
+ result->key = malloc(strlen(key)+1);
+ strcpy(result->key, key);
+ result->data = item->data;
+ result->length = item->length;
+ return result;
}
return NULL;
@@ -143,7 +151,7 @@
*/
bool
lru_table_update(struct lru_table* table,
- char* key, char* value, int offset)
+ char* key, char* value, int offset, int length)
{
SHOW_FSSI(key,value,offset);
@@ -160,13 +168,12 @@
char* data = item->data;
- int dl = strlen(data);
- int vl = strlen(value);
+ int dl = length;
+ int vl = item->length;
int ul = max(dl, offset+vl);
char* update = malloc(ul+1);
- update[ul] = '\0';
- strncpy(update, data, dl);
+ memcpy(update, data, dl);
memcpy(update+offset, value, vl);
item->data = update;
@@ -206,9 +213,10 @@
// NOTE_S("OLDEST: ", ((struct dpkm_list_item*) oldest->ptr)->key);
dpkm_list_excise(table->array[oldest_index], oldest->ptr);
result = (struct keyvalue*) MALLOC(sizeof(struct keyvalue));
- result->key = oldest->key;
- // SHOW_S(result->key);
- result->data = oldest->data;
+ // SHOW_S(oldest->key);
+ result->key = oldest->key;
+ result->data = oldest->data;
+ result->length = oldest->length;
FREE(oldest->ptr);
FREE(oldest);
}
Modified: branches/code/dense-1/src/cmpi/cmpi.c
===================================================================
--- branches/code/dense-1/src/cmpi/cmpi.c 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/src/cmpi/cmpi.c 2009-04-30 22:49:07 UTC (rev 466)
@@ -103,61 +103,59 @@
return CMPI_SUCCESS;
}
-void
+int
cmpi_cached_retrieve(char* key, char** data)
{
- // NOTE_F;
+ int result;
+ NOTE_F;
+
// DEBUG(lru_table_fprintf(debug_file, "%s", cmpi_cache));
- *data = lru_table_search(cmpi_cache, key);
+ struct keyvalue* found = lru_table_search(cmpi_cache, key);
+ *data = found->data;
+ result = found->length;
+ free(found->key);
+ free(found);
+ NOTE_FS(*data);
if (data == NULL)
{
- cmpi_disk_loadpair(key, data);
+ result = cmpi_disk_loadpair(key, data);
if (data != NULL)
{
- struct keyvalue* kv = lru_table_add(cmpi_cache, key, *data);
+ struct keyvalue* kv = lru_table_add(cmpi_cache, key, *data, result);
if (kv)
{
- cmpi_disk_storepair(kv->key, kv->data);
+ cmpi_disk_storepair(kv->key, kv->data, kv->length);
keyvalue_destroy(kv);
}
}
}
+ return result;
}
/**
*/
void
-cmpi_cached_store(char* key, char* data)
+cmpi_cached_store(char* key, char* data, int length)
{
struct keyvalue* kv;
SHOW_FSS(key,data);
- kv = lru_table_add(cmpi_cache, key, data);
- // DEBUG(lru_table_fprintf(debug_file, "%s", cmpi_cache));
+ kv = lru_table_add(cmpi_cache, key, data, length);
if (kv)
{
-
- /*
- // NOTE("OK");
- // SHOW_P(kv);
- // SHOW_S(kv->key);
- // SHOW_P(kv->key);
- // SHOW_S(kv->data); */
- cmpi_disk_storepair(kv->key, kv->data);
- FREE(kv->key);
- FREE(kv);
+ cmpi_disk_storepair(kv->key, kv->data, length);
+ free(kv->key);
+ free(kv);
}
- NOTE("cmpi_cached_store() done");
- // DEBUG(lru_table_dump("%s", cmpi_cache));
}
void
-cmpi_cached_update(char* key, char* data, int offset)
+cmpi_cached_update(char* key, char* data, int offset, int length)
{
SHOW_FSSI(key,data,offset);
if (lru_table_search(cmpi_cache, key))
{
- lru_table_update(cmpi_cache, key, data, offset);
+ lru_table_update(cmpi_cache, key, data, offset, length);
}
else
{
@@ -167,11 +165,11 @@
char* update = malloc(offset+dl+1);
memset(update, ' ', offset);
strcpy(update+offset, data);
- lru_table_add(cmpi_cache, key, update);
+ lru_table_add(cmpi_cache, key, update, length);
}
else
{
- lru_table_add(cmpi_cache, key, data);
+ lru_table_add(cmpi_cache, key, data, length);
}
}
DEBUG(lru_table_fprintf(debug_file, "%s", cmpi_cache));
Modified: branches/code/dense-1/src/cmpi/cmpi_disk_void.c
===================================================================
--- branches/code/dense-1/src/cmpi/cmpi_disk_void.c 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/src/cmpi/cmpi_disk_void.c 2009-04-30 22:49:07 UTC (rev 466)
@@ -7,12 +7,13 @@
#include <mpi_tools.h>
void
-cmpi_disk_storepair(char* key, char* value)
+cmpi_disk_storepair(char* key, char* value, int length)
{
NOTE_FS(key);
}
-void cmpi_disk_loadpair(char* key, char** value)
+int cmpi_disk_loadpair(char* key, char** value)
{
- NOTE_F;
+ NOTE_F;
+ return 0;
}
Modified: branches/code/dense-1/src/cmpi/driver.c
===================================================================
--- branches/code/dense-1/src/cmpi/driver.c 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/src/cmpi/driver.c 2009-04-30 22:49:07 UTC (rev 466)
@@ -85,18 +85,50 @@
driver_put(cmpi_driver* driver, struct list* tokens)
{
char* key = tokens->head->next->data;
- char* value = tokens->head->next->next->data;
- cmpi_put(key, value);
- fprintf(driver->sink, "put %s ok\n", key);
+ int length;
+ sscanf(tokens->head->next->next->data, "%i", &length);
+
+ SHOW_FSI(key, length);
+
+ char value[CMPI_VALUE_LENGTH];
+
+ int total = 0;
+ while (total < length)
+ {
+ int chunk = length-total;
+ SHOW_I(chunk);
+ int actual = fread(value+total, 1, chunk, driver->source);
+ value[total+actual] = '\0';
+ SHOW_I(actual);
+ SHOW_S(value);
+ total += actual;
+ sleep(1);
+ }
+
+ cmpi_put(key, value, total);
+
+ fprintf(driver->sink, "ok\n");
+ fflush(driver->sink);
}
void
-driver_get(struct list* tokens)
+driver_get(cmpi_driver* driver, struct list* tokens)
{
- char* p = tokens->head->next->data;
+ char* key = tokens->head->next->data;
+
char* value;
- cmpi_get(p, &value);
- printf("got: %s \n", value);
+ int length;
+ cmpi_get(key, &value, &length);
+ printf("got: %s \n", value);
+
+ fprintf(driver->sink, "length: %i\n", length);
+ fflush(driver->sink);
+
+ printf("wrote length\n");
+
+ // fwritef(driver->sink, "%s", value);
+ fflush(driver->sink);
+ DONE;
}
void
@@ -143,8 +175,8 @@
struct list* tokens = list_parse(driver->command);
- printf("got tokens: ");
- list_printf("%s", tokens);
+ gossip_ldebug(MASK_DRIVER, "got tokens: \n");
+ gossip_do(MASK_DRIVER, list_printf("%s", tokens));
if (tokens->size == 0)
return;
@@ -160,7 +192,7 @@
}
else if (strncmp(optoken, "get", 4) == 0)
{
- driver_get(tokens);
+ driver_get(driver, tokens);
}
else if (strncmp(optoken, "lookup", 6) == 0)
{
@@ -185,16 +217,16 @@
void
driver_process(cmpi_driver* driver)
{
- gossip_ldebug(MASK_DRIVER, "\n");
- while (fgets(driver->command,
- CMPI_DRIVER_MAX_COMMAND,
- driver->source) != NULL)
+ gossip_ldebug(MASK_DRIVER, "\n");
+ while (! driver->quitting)
{
+ char* result =
+ fgets(driver->command, CMPI_DRIVER_MAX_COMMAND, driver->source);
+ if (!result)
+ break;
char* s = strchr(driver->command, '\n');
*s = '\0';
driver_execute(driver);
- if (driver->quitting)
- break;
}
fclose(driver->source);
fclose(driver->sink);
Modified: branches/code/dense-1/src/cmpi/module.mk.in
===================================================================
--- branches/code/dense-1/src/cmpi/module.mk.in 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/src/cmpi/module.mk.in 2009-04-30 22:49:07 UTC (rev 466)
@@ -4,6 +4,7 @@
CMPI_SRC += $(DIR)/cmpi.c
CMPI_SRC += $(DIR)/node.c
CMPI_SRC += $(DIR)/driver.c
+CMPI_SRC += $(DIR)/accessor.c
ifeq (@USE_TABLE_DENSE@,1)
CMPI_SRC += $(DIR)/dense.c
Modified: branches/code/dense-1/src/cmpi/node.c
===================================================================
--- branches/code/dense-1/src/cmpi/node.c 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/src/cmpi/node.c 2009-04-30 22:49:07 UTC (rev 466)
@@ -156,7 +156,7 @@
int
main(int argc, char* argv[])
{
- gossip_set_debug_mask(1, MASK_DEBUG|MASK_MPIRPC|MASK_DRIVER);
+ gossip_set_debug_mask(1, MASK_DEBUG|MASK_DRIVER);
// Comment out to achieve deterministic results:
srand((unsigned int) time(NULL));
Modified: branches/code/dense-1/src/dense-1/cmpi_dense.c
===================================================================
--- branches/code/dense-1/src/dense-1/cmpi_dense.c 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/src/dense-1/cmpi_dense.c 2009-04-30 22:49:07 UTC (rev 466)
@@ -103,8 +103,11 @@
return result;
}
+/**
+ Blocking call.
+*/
CMPI_RETURN
-cmpi_put(char* key, char* value)
+cmpi_put(char* key, char* value, int length)
{
struct inlist_item* item;
MPIRPC_Node node;
@@ -122,7 +125,7 @@
{
SHOW_I(item->data);
MPIRPC_Node_make(MPI_COMM_WORLD, item->data, &node);
- MPIRPC* rpc = DENSE_Store(node, key, heap(value));
+ MPIRPC* rpc = DENSE_Store(node, key, value, length);
MPIRPC_Wait(rpc);
MPIRPC_Free(rpc);
NOTE("freed");
Modified: branches/code/dense-1/src/dense-1/dense.c
===================================================================
--- branches/code/dense-1/src/dense-1/dense.c 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/src/dense-1/dense.c 2009-04-30 22:49:07 UTC (rev 466)
@@ -143,10 +143,10 @@
/**
Instruct a node to store a value.
- Asynchronous. Copies key and value into MPIRPC.
+ Asynchronous. Copies key into MPIRPC.
*/
MPIRPC*
-DENSE_Store(MPIRPC_Node node, char* key, char* value)
+DENSE_Store(MPIRPC_Node node, char* key, char* value, int length)
{
NOTE_F;
int klength = strlen(key);
@@ -154,23 +154,24 @@
char* args = malloc((klength+vlength+5)*sizeof(char));
assert(args);
strcpy(args, key);
- args[klength] = ' ';
- strcpy(args+klength+1, value);
- MPIRPC* rpc = MPIRPC_Call(node, "store", args,
- NULL, MPIRPC_PROCEED_NULL);
+ MPIRPC* rpc = MPIRPC_Call_blob(node, "store", key,
+ value, length,
+ NULL, MPIRPC_PROCEED_NULL);
return rpc;
}
/**
Instruct a node to retrieve a value.
- Asynchronous. Copies key and value into MPIRPC.
+ Asynchronous. Copies key into MPIRPC.
+ User must use MPIRPC->result_length
+ to find number of bytes retrieved.
*/
MPIRPC*
DENSE_Retrieve(MPIRPC_Node node, char* key)
{
MPIRPC* rpc =
- MPIRPC_Call(node, "retrieve", heap(key),
+ MPIRPC_Call(node, "retrieve", heap(key),
NULL, MPIRPC_PROCEED_NULL);
return rpc;
}
@@ -182,37 +183,41 @@
}
void
-handle_bootping(MPIRPC_Node caller, int unique, char* args)
+handle_bootping(MPIRPC_Node caller, int unique, char* args, char* blob, int blength)
{
- MPIRPC_Return(caller, unique, NULL);
+ MPIRPC_Null(caller, unique);
rpc_bootping();
}
void
-handle_info(MPIRPC_Node caller, int unique, char* args)
+handle_info(MPIRPC_Node caller, int unique, char* args,
+ char* blob, int blength)
{
- MPIRPC_Return(caller, unique, NULL);
+ MPIRPC_Null(caller, unique);
}
void
-handle_ping(MPIRPC_Node caller, int unique, char* args)
+handle_ping(MPIRPC_Node caller, int unique, char* args,
+ char* blob, int blength)
{
- MPIRPC_Return(caller, unique, NULL);
+ MPIRPC_Null(caller, unique);
}
void
-handle_query_id(MPIRPC_Node caller, int unique, char* args)
+handle_query_id(MPIRPC_Node caller, int unique, char* args,
+ char* blob, int blength)
{
int object_id;
sscanf(args, "%X", &object_id);
int other_rank = object_id % dense_nodes;
char* result = malloc(10*sizeof(char));
- sprintf(result, "%i", other_rank);
- MPIRPC_Return(caller, unique, result);
+ int blength = sprintf(result, "%i", other_rank);
+ MPIRPC_Return(caller, unique, result, blength);
}
void
-handle_query_id_k(MPIRPC_Node caller, int unique, char* args)
+handle_query_id_k(MPIRPC_Node caller, int unique, char* args,
+ char* blob, int blength)
{
int i;
int object_id;
@@ -225,31 +230,23 @@
inlist_add(ranks, other_rank);
}
char* result = inlist_serialize(ranks);
- MPIRPC_Return(caller, unique, result);
+ MPIRPC_Return(caller, unique, result, strlen(result));
}
void
-handle_store(MPIRPC_Node caller, int unique, char* args)
+handle_store(MPIRPC_Node caller, int unique, char* args,
+ char* blob, int blength)
{
- int args_length = strlen(args);
- char* p = index(args, ' ');
- int key_length = p-args+1;
- int value_length = args_length-key_length;
- char* key = malloc((key_length+1) * sizeof(char));
- char* value = malloc((value_length+1) * sizeof(char));
- strncpy(key, args, p-args);
- key[p-args] = '\0';
- strncpy(value, p+1, value_length+1);
-
- NOTE_S("store: ", key);
- cmpi_cached_store(key, value);
+ NOTE_S("store: ", args);
+ cmpi_cached_store(args, blob, blength);
DEBUG(lru_table_printf("%s", cmpi_cache));
- MPIRPC_Return(caller, unique, NULL);
+ MPIRPC_Null(caller, unique);
}
void
-handle_retrieve(MPIRPC_Node caller, int unique, char* args)
+handle_retrieve(MPIRPC_Node caller, int unique, char* args,
+ char* blob, int blength)
{
NOTE_FS(args);
DEBUG(lru_table_printf("%s", cmpi_cache));
@@ -262,7 +259,8 @@
}
void
-handle_quit(MPIRPC_Node caller, int unique, char* args)
+handle_quit(MPIRPC_Node caller, int unique, char* args,
+ char* blob, int blength)
{
MPIRPC_Return(caller, unique, NULL);
sleep(1);
Modified: branches/code/dense-1/src/include/cmpi.h
===================================================================
--- branches/code/dense-1/src/include/cmpi.h 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/src/include/cmpi.h 2009-04-30 22:49:07 UTC (rev 466)
@@ -213,17 +213,17 @@
/**
Retrieve a key/value pair from CMPI.
*/
-CMPI_RETURN cmpi_get(char* key, char** value);
+CMPI_RETURN cmpi_get(char* key, char** value, int* length);
/**
Store a key/value pair in CMPI.
*/
-CMPI_RETURN cmpi_put(char* key, char* value);
+CMPI_RETURN cmpi_put(char* key, char* value, int length);
/**
Update byte region in CMPI key/value pair.
*/
-CMPI_RETURN cmpi_update(char* key, char* value, int offset);
+CMPI_RETURN cmpi_update(char* key, char* value, int offset, int length);
/**
Global operation.
@@ -235,9 +235,10 @@
//// Cached disk operations:
-void cmpi_cached_retrieve(char* key, char** data);
-void cmpi_cached_store(char* key, char* data);
-void cmpi_cached_update(char* key, char* data, int offset);
+int cmpi_cached_retrieve(char* key, char** data);
+void cmpi_cached_store(char* key, char* data, int length);
+void cmpi_cached_update(char* key, char* data,
+ int offset, int length);
/**
Global operation. Instruct all nodes to shutdown.
Modified: branches/code/dense-1/src/include/cmpi_disk.h
===================================================================
--- branches/code/dense-1/src/include/cmpi_disk.h 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/src/include/cmpi_disk.h 2009-04-30 22:49:07 UTC (rev 466)
@@ -3,6 +3,6 @@
* Select disk operations based on configure-time value of DISK_TYPE.
* */
-void cmpi_disk_storepair(char* key, char* value);
-void cmpi_disk_loadpair(char* key, char** value);
+void cmpi_disk_storepair(char* key, char* value, int length);
+int cmpi_disk_loadpair(char* key, char** value);
Modified: branches/code/dense-1/src/include/dense-1.h
===================================================================
--- branches/code/dense-1/src/include/dense-1.h 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/src/include/dense-1.h 2009-04-30 22:49:07 UTC (rev 466)
@@ -22,20 +22,20 @@
MPIRPC* DENSE_Lookup_k(MPIRPC_Node node, char* key);
MPIRPC* DENSE_Translate(MPIRPC_Node node, DENSE_ID id);
MPIRPC* DENSE_Translate_k(MPIRPC_Node node, DENSE_ID id);
-MPIRPC* DENSE_Store(MPIRPC_Node node, char* key, char* value);
-MPIRPC* DENSE_Retrieve(MPIRPC_Node node, char* key);
+MPIRPC* DENSE_Store(MPIRPC_Node node, char* key, char* value, int length);
+MPIRPC* DENSE_Retrieve(MPIRPC_Node node, char* key);
void DENSE_Shutdown(MPIRPC_Node node);
void rpc_bootping(void);
void listen_loop(void);
-void handle_bootping(MPIRPC_Node caller, int unique, char* args);
-void handle_info(MPIRPC_Node caller, int unique, char* args);
-void handle_ping(MPIRPC_Node caller, int unique, char* args);
-void handle_query_id(MPIRPC_Node caller, int unique, char* args);
-void handle_query_id_k(MPIRPC_Node caller, int unique, char* args);
-void handle_store(MPIRPC_Node caller, int unique, char* args);
-void handle_retrieve(MPIRPC_Node caller, int unique, char* args);
-void handle_quit(MPIRPC_Node caller, int unique, char* args);
+void handle_bootping(MPIRPC_Node caller, int unique, char* args, char* blob, int blength);
+void handle_info(MPIRPC_Node caller, int unique, char* args, char* blob, int blength);
+void handle_ping(MPIRPC_Node caller, int unique, char* args, char* blob, int blength);
+void handle_query_id(MPIRPC_Node caller, int unique, char* args, char* blob, int blength);
+void handle_query_id_k(MPIRPC_Node caller, int unique, char* args, char* blob, int blength);
+void handle_store(MPIRPC_Node caller, int unique, char* args, char* blob, int blength);
+void handle_retrieve(MPIRPC_Node caller, int unique, char* args, char* blob, int blength);
+void handle_quit(MPIRPC_Node caller, int unique, char* args, char* blob, int blength);
#endif
Modified: branches/code/dense-1/src/include/dpkm_list.h
===================================================================
--- branches/code/dense-1/src/include/dpkm_list.h 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/src/include/dpkm_list.h 2009-04-30 22:49:07 UTC (rev 466)
@@ -25,7 +25,8 @@
{
void* ptr;
char* key;
- void* data;
+ char* data;
+ int length;
struct dpkm_list_item* prev;
struct dpkm_list_item* next;
};
@@ -41,9 +42,10 @@
struct dpkm_list* dpkm_list_create(int limit);
struct dpkm_list_item* dpkm_list_add(struct dpkm_list* target,
- char* key, void* data);
-#define dpkm_list_push(target, data) dpkm_list_add(target, data)
+ char* key, void* data, int length);
+// #define dpkm_list_push(target, key, data, length) dpkm_list_add(target, key, data, length)
+
void dpkm_list_pushback(struct dpkm_list* target,
struct dpkm_list_item* item);
Modified: branches/code/dense-1/src/include/keyvalue.h
===================================================================
--- branches/code/dense-1/src/include/keyvalue.h 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/src/include/keyvalue.h 2009-04-30 22:49:07 UTC (rev 466)
@@ -6,10 +6,9 @@
struct keyvalue
{
- int key_length;
char* key;
- int data_length;
- void* data;
+ int length;
+ char* data;
};
void keyvalue_destroy(struct keyvalue* kv);
Modified: branches/code/dense-1/src/include/lru_table.h
===================================================================
--- branches/code/dense-1/src/include/lru_table.h 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/src/include/lru_table.h 2009-04-30 22:49:07 UTC (rev 466)
@@ -30,12 +30,12 @@
struct lru_table* lru_table_create(int capacity, int limit);
struct keyvalue* lru_table_add(struct lru_table *table,
- char* key, char* data);
+ char* key, char* data, int length);
bool lru_table_update(struct lru_table *table,
- char* key, char* data, int offset);
+ char* key, char* data, int offset, int length);
-char* lru_table_search(struct lru_table* table, char* key);
+struct keyvalue* lru_table_search(struct lru_table* table, char* key);
struct keyvalue* lru_table_poll(struct lru_table* table);
Modified: branches/code/dense-1/src/include/mpirpc-2.h
===================================================================
--- branches/code/dense-1/src/include/mpirpc-2.h 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/src/include/mpirpc-2.h 2009-04-30 22:49:07 UTC (rev 466)
@@ -42,6 +42,7 @@
char name[MPIRPC_MAX_NAME];
char* args;
char* result;
+ int result_length;
void* extras;
void (*proceed) (struct mpirpc* rpc);
int unique;
@@ -49,13 +50,15 @@
// Internals:
/**
- name_length is transferred via Isend(), needs heap memory.
+ name_length is transferred via Isend().
*/
int name_length;
+
/**
- args_length is transferred via Isend(), needs heap memory.
+ args_length is transferred via Isend().
*/
- int args_length;
+ int args_length;
+
/**
Array of Isend() requests to be freed on return.
*/
@@ -82,7 +85,7 @@
bool MPIRPC_Check(void);
void MPIRPC_Register(char* name,
- void (*f)(MPIRPC_Node, int, char*));
+ void (*f)(MPIRPC_Node,int,char*,char*,int));
bool MPIRPC_Comm_add(MPI_Comm comm);
void MPIRPC_Close(MPIRPC_Channel* channel);
@@ -90,12 +93,22 @@
MPIRPC* MPIRPC_Call(MPIRPC_Node target, char* name, char* args,
void* extras, void (*proceed)(MPIRPC*));
+MPIRPC* MPIRPC_Call_blob(MPIRPC_Node target, char* name, char* args,
+ char* blob, int blength,
+ void* extras, void (*proceed)(MPIRPC*));
+
char* MPIRPC_Block(MPIRPC_Node target, char* name, char* args);
+char* MPIRPC_Block_blob(MPIRPC_Node target, char* name, char* args,
+ char* blob, int blength);
+
char* MPIRPC_Wait(MPIRPC* rpc);
-void MPIRPC_Return(MPIRPC_Node caller, int unique, char* result);
+void MPIRPC_Null(MPIRPC_Node caller, int unique);
+void MPIRPC_Return(MPIRPC_Node caller, int unique,
+ char* result, int rlength);
+
MPIRPC_Node* MPIRPC_Node_create(MPI_Comm comm, int rank);
MPIRPC_Node* MPIRPC_Node_make(MPI_Comm comm, int rank, MPIRPC_Node* node);
@@ -128,7 +141,7 @@
void MPIRPC_Value_free(MPIRPC_Value* value);
-MPIRPC_Value* MPIRPC_Value_create(int unique, char* result);
+MPIRPC_Value* MPIRPC_Value_create(int unique, char* result, int length);
//// Data structure helpers...
Modified: branches/code/dense-1/src/mpirpc-2/mpirpc.c
===================================================================
--- branches/code/dense-1/src/mpirpc-2/mpirpc.c 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/src/mpirpc-2/mpirpc.c 2009-04-30 22:49:07 UTC (rev 466)
@@ -100,7 +100,7 @@
Register a new RPC for remote access.
*/
void
-MPIRPC_Register(char* name, void (*f)(MPIRPC_Node,int,char*))
+MPIRPC_Register(char* name, void (*f)(MPIRPC_Node,int,char*,char*,int))
{
hashtable_add(portmap, name, f);
}
@@ -158,7 +158,7 @@
bool
MPIRPC_Comm_remove(MPI_Comm* comm)
{
- NOTE_F;
+ gossip_do(MASK_MPIRPC, NOTE_F);
bool disconnected = false;
@@ -192,6 +192,7 @@
MPIRPC*
MPIRPC_Create(MPIRPC_Node target, char* name, char* args,
+ char* blob, int blength,
void* extras, void (*proceed)(MPIRPC*))
{
MPIRPC* rpc = malloc(sizeof(MPIRPC));
@@ -199,6 +200,8 @@
rpc->unique = ++unique;
rpc->target = target;
rpc->args = args;
+ rpc->blob = blob;
+ rpc->blength = blength;
rpc->extras = extras;
rpc->proceed = proceed;
rpc->cancelled = false;
@@ -226,16 +229,29 @@
@param extras Extra state to pass to proceed.
@param proceed The procedure to call when the RPC returns.
*/
-MPIRPC*
+MPIRPC*
MPIRPC_Call(MPIRPC_Node target, char* name, char* args,
void* extras, void (*proceed)(MPIRPC* rpc))
{
+ return MPIRPC_Call_blob(target, name, args,
+ NULL, 0, extras, proceed);
+}
+
+MPIRPC*
+MPIRPC_Call_blob(MPIRPC_Node target, char* name, char* args,
+ char* blob, int blength,
+ void* extras, void (*proceed)(MPIRPC* rpc))
+{
assert(target.comm != MPI_COMM_NULL);
- MPIRPC* rpc = MPIRPC_Create(target, name, args, extras, proceed);
+ MPIRPC* rpc = MPIRPC_Create(target, name, args,
+ blob, blength, extras, proceed);
- DEBUG(char* commname = MPIRPC_Comm_get_name(target.comm));
- SHOW_FSISSI(commname, target.rank, name, args, rpc->unique);
+ // gossip_do(MASK_MPIRPC,
+ // char* commname = MPIRPC_Comm_get_name(target.comm));
+ gossip_do(MASK_MPIRPC,
+ SHOW_FSISSI(target.rank, name,
+ args, rpc->unique));
MPI_Isend(&mpirpc_msg_call, 1, MPI_INT, target.rank,
MPIRPC_TAG_CONTROL, target.comm, &rpc->request[0]);
@@ -262,6 +278,21 @@
MPIRPC_TAG_LENGTH, target.comm, &rpc->request[4]);
}
+ if (blob)
+ {
+ MPI_Isend(blength, 1, MPI_INT, target.rank,
+ MPIRPC_TAG_LENGTH, target.comm, &rpc->request[4]);
+ MPI_Isend(blob, blength, MPI_CHAR, target.rank,
+ MPIRPC_TAG_ARGS, target.comm, &rpc->request[5]);
+ }
+ else
+ {
+ blength = -1;
+ MPI_Isend(&blength, 1, MPI_INT, target.rank,
+ MPIRPC_TAG_LENGTH, target.comm, &rpc->request[4]);
+ }
+
+
rpc->status = MPIRPC_STATUS_CALLED;
itable_add(rpctable, rpc->unique, rpc);
@@ -277,9 +308,17 @@
char*
MPIRPC_Block(MPIRPC_Node target, char* name, char* args)
{
+ return MPIRPC_Block_blob(target, name, args, NULL, 0);
+}
+
+char*
+MPIRPC_Block_blob(MPIRPC_Node target, char* name, char* args,
+ char* blob, int blength)
+{
char* result;
- NOTE_FS(name);
- MPIRPC* rpc = MPIRPC_Call(target, name, args, NULL, NULL);
+ gossip_do(MASK_MPIRPC, NOTE_FS(name));
+ MPIRPC* rpc = MPIRPC_Call(target, name, args,
+ blob, blength, NULL, NULL);
MPIRPC_Wait(rpc);
gossip_do(MASK_MPIRPC, NOTE_S("Unblocked: ", name));
result = rpc->result;
@@ -292,11 +331,14 @@
{
MPI_Status status;
- char name[MPIRPC_MAX_NAME];
- int unique;
- int name_length = 32;
- int args_length;
-
+ char name[MPIRPC_MAX_NAME];
+ int unique;
+ int name_length = 32;
+ int args_length;
+ char* args;
+ int blength;
+ char* blob;
+
// DEBUG(MPIRPC_Dump_channels());
MPI_Recv(&name_length, 1, MPI_INT, caller.rank,
@@ -308,9 +350,8 @@
MPI_Recv(&args_length, 1, MPI_INT, caller.rank,
MPIRPC_TAG_LENGTH, caller.comm, &status);
- NOTE_FS(name);
+ gossip_do(MASK_MPIRPC, NOTE_FS(name));
- char* args;
if (args_length > 0)
{
args = malloc((args_length+10)*sizeof(char));
@@ -323,6 +364,16 @@
else
args = NULL;
+ MPI_Recv(&blength, 1, MPI_INT, caller.rank,
+ MPIRPC_TAG_LENGTH, caller.comm, &status);
+
+ if (blength > 0)
+ {
+ blob = malloc((blength+1)*sizeof(char));
+
+ MPI_Recv(blob, blength+1, MPI_CHAR, caller.rank,
+ MPIRPC_TAG_ARGS, caller.comm, &status);
+ }
/* printf("\t [%i] %s(%s) for %i \n",
mpi_rank, name, args, caller); */
@@ -331,19 +382,30 @@
if (f == NULL)
printf("No such method: %s \n", name);
else
- f(caller, unique, args);
+ f(caller, unique, args, blob, blength);
}
/**
+ Convenience for MPIRPC_Return(NULL).
+ Return null to caller.
+*/
+void
+MPIRPC_Null(MPIRPC_Node caller, int unique)
+{
+ MPIRPC_Return(caller, unique, NULL, 0);
+}
+
+/**
Return result to caller for unique RPC.
result is asynchronously freed upon completion.
*/
void
-MPIRPC_Return(MPIRPC_Node caller, int unique, char* result)
+MPIRPC_Return(MPIRPC_Node caller, int unique, char* result, int length)
{
- SHOW_FXIIS(caller.comm, caller.rank, unique, result);
+ gossip_do(MASK_MPIRPC,
+ SHOW_FXIIS(caller.comm, caller.rank, unique, result));
- MPIRPC_Value* value = MPIRPC_Value_create(unique, result);
+ MPIRPC_Value* value = MPIRPC_Value_create(unique, result, length);
// SHOW_P(&value->request[0]);
MPI_Isend(&mpirpc_msg_return, 1, MPI_INT, caller.rank,
@@ -354,7 +416,7 @@
MPIRPC_TAG_LENGTH, caller.comm, &value->request[2]);
if (value->length >= 0)
MPI_Isend(value->result, value->length+1, MPI_CHAR, caller.rank,
- MPIRPC_TAG_RESULT, caller.comm, &value->request[3]);
+ MPIRPC_TAG_RESULT, caller.comm, &value->request[3]);
list_push(garbage_values, value);
MPIRPC_Garbage_collect();
@@ -376,26 +438,26 @@
MPI_Recv(&unique, 1, MPI_INT, sender.rank,
MPIRPC_TAG_UNIQUE, sender.comm, &status);
- SHOW_FII(sender.rank, unique);
+ gossip_do(MASK_MPIRPC, SHOW_FII(sender.rank, unique));
MPIRPC* rpc = (MPIRPC*) MPIRPC_Remove(unique);
assert(rpc != NULL);
- MPI_Recv(&length, 1, MPI_INT, sender.rank,
+ MPI_Recv(&rpc->result_length, 1, MPI_INT, sender.rank,
MPIRPC_TAG_LENGTH, sender.comm, &status);
- if (length >= 0)
+ if (rpc->result_length > 0)
{
rpc->result = (char*) malloc((length+1)*sizeof(char));
- MPI_Recv(rpc->result, length+1, MPI_CHAR, sender.rank,
+ MPI_Recv(rpc->result, rpc->result_length+1, MPI_CHAR, sender.rank,
MPIRPC_TAG_RESULT, sender.comm, &status);
}
else
{
rpc->result = NULL;
}
-
+
MPI_Request* r = rpc->request;
for (i = 0; i < 5; i++)
MPI_Request_free(&r[i]);
@@ -476,7 +538,7 @@
{
struct list_item* item;
int i;
- NOTE_F;
+ gossip_do(MASK_MPIRPC, NOTE_F);
MPI_Status status;
for (item = garbage_values->head;
item; item = item->next)
@@ -485,7 +547,6 @@
for (i = 0; i < 3; i++)
{
MPI_Wait(&value->request[i], &status);
- NOTE(" Waited");
}
if (value->length >= 0)
@@ -788,7 +849,7 @@
void
MPIRPC_Finalize()
{
- NOTE_F;
+ gossip_do(MASK_MPIRPC, NOTE_F);
list_destroy(channels);
Modified: branches/code/dense-1/test/adts/module.mk.in
===================================================================
--- branches/code/dense-1/test/adts/module.mk.in 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/test/adts/module.mk.in 2009-04-30 22:49:07 UTC (rev 466)
@@ -1,11 +1,11 @@
-TEST_SRCS += test/adts/testgossip.c
-TEST_SRCS += test/adts/testgossip-env.c
+TEST_SRC += test/adts/testgossip.c
+TEST_SRC += test/adts/testgossip-env.c
-#TEST_SRCS += $(shell cd @SRC_ABSOLUTE_TOP@; find test/adts -name "*.c")
-#TEST_OBJS += $(patsubst %.c, %.o, $(TEST_SRCS))
-#TEST_PROGS += $(patsubst %.c, %.x, $(TEST_SRCS))
-#TEST_OUTPUT += $(patsubst %.c, %.out, $(TEST_SRCS))
+#TEST_SRC += $(shell cd @SRC_ABSOLUTE_TOP@; find test/adts -name "*.c")
+#TEST_OBJS += $(patsubst %.c, %.o, $(TEST_SRC))
+#TEST_PROGS += $(patsubst %.c, %.x, $(TEST_SRC))
+#TEST_OUTPUT += $(patsubst %.c, %.out, $(TEST_SRC))
test/adts/test%.x: test/adts/test%.o $(CMPI)
$(Q) " LINK $(@) "
Modified: branches/code/dense-1/test/cmpi/module.mk.in
===================================================================
--- branches/code/dense-1/test/cmpi/module.mk.in 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/test/cmpi/module.mk.in 2009-04-30 22:49:07 UTC (rev 466)
@@ -9,9 +9,9 @@
# is actually called.
-TEST_CMPI_SRCS += $(shell cd @SRC_ABSOLUTE_TOP@; find test/cmpi -name "*.c" ! -name test_helpers.c)
-TEST_SRCS += $(TEST_CMPI_SRCS)
-TEST_HELPER_SRCS += test/cmpi/test_helpers.c
+TEST_CMPI_SRC += $(shell cd @SRC_ABSOLUTE_TOP@; find test/cmpi -name "*.c" ! -name test_helpers.c)
+TEST_SRC += $(TEST_CMPI_SRCS)
+TEST_HELPER_SRC += test/cmpi/test_helpers.c
ifeq (@USE_COMM_WORLD@,1)
Modified: branches/code/dense-1/test/disksim/module.mk.in
===================================================================
--- branches/code/dense-1/test/disksim/module.mk.in 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/test/disksim/module.mk.in 2009-04-30 22:49:07 UTC (rev 466)
@@ -1,13 +1,13 @@
ifneq (@USE_DISKSIM@,0)
-TEST_DISKSIM_SRCS += $(shell cd @SRC_ABSOLUTE_TOP@; find test/disksim -name "*.c")
+TEST_DISKSIM_SRC += $(shell cd @SRC_ABSOLUTE_TOP@; find test/disksim -name "*.c")
-TEST_SRCS += $(TEST_DISKSIM_SRCS)
+TEST_SRC += $(TEST_DISKSIM_SRCS)
-#TEST_OBJS += $(patsubst %.c, %.o, $(TEST_SRCS))
-#TEST_PROGS += $(patsubst %.c, %.x, $(TEST_SRCS))
-#TEST_OUTPUT += $(patsubst %.c, %.out, $(TEST_SRCS))
+#TEST_OBJS += $(patsubst %.c, %.o, $(TEST_SRC))
+#TEST_PROGS += $(patsubst %.c, %.x, $(TEST_SRC))
+#TEST_OUTPUT += $(patsubst %.c, %.out, $(TEST_SRC))
Modified: branches/code/dense-1/test/gossip/module.mk.in
===================================================================
--- branches/code/dense-1/test/gossip/module.mk.in 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/test/gossip/module.mk.in 2009-04-30 22:49:07 UTC (rev 466)
@@ -1,7 +1,7 @@
-TEST_SRCS += $(shell cd @SRC_ABSOLUTE_TOP@; find test/gossip -name "*.c")
-#TEST_PROGS += $(patsubst %.c, %.x, $(TEST_SRCS))
-#TEST_OUTPUT += $(patsubst %.c, %.out, $(TEST_SRCS))
+TEST_SRC += $(shell cd @SRC_ABSOLUTE_TOP@; find test/gossip -name "*.c")
+#TEST_PROGS += $(patsubst %.c, %.x, $(TEST_SRC))
+#TEST_OUTPUT += $(patsubst %.c, %.out, $(TEST_SRC))
test/gossip/test%.x: test/gossip/test%.o $(CMPI)
$(Q) " LINK $(@) "
Modified: branches/code/dense-1/test/mpi_tools/module.mk.in
===================================================================
--- branches/code/dense-1/test/mpi_tools/module.mk.in 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/test/mpi_tools/module.mk.in 2009-04-30 22:49:07 UTC (rev 466)
@@ -1,8 +1,8 @@
ifeq (@USE_COMM_WORLD@,1)
-TEST_MPITOOLS_SRCS += $(shell cd @SRC_ABSOLUTE_TOP@; find test/mpi_tools -name "*.c")
-TEST_SRCS += $(TEST_MPITOOLS_SRCS)
+TEST_MPITOOLS_SRC += $(shell cd @SRC_ABSOLUTE_TOP@; find test/mpi_tools -name "*.c")
+TEST_SRC += $(TEST_MPITOOLS_SRCS)
test/mpi_tools/test%.out: test/mpi_tools/test%.x
$(LAUNCH) -n $(NODES) $(<) > $(@) 2>&1
Modified: branches/code/dense-1/test/mpirpc-1/module.mk.in
===================================================================
--- branches/code/dense-1/test/mpirpc-1/module.mk.in 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/test/mpirpc-1/module.mk.in 2009-04-30 22:49:07 UTC (rev 466)
@@ -3,8 +3,8 @@
ifeq (@USE_COMM_WORLD@,1)
-TEST_MPIRPC_SRCS += $(shell cd @SRC_ABSOLUTE_TOP@; find $(DIR) -name "*.c" ! -name ilog2.c ! -name accept1.c ! -name connect1.c)
-TEST_SRCS += $(TEST_MPIRPC_SRCS)
+TEST_MPIRPC_SRC += $(shell cd @SRC_ABSOLUTE_TOP@; find $(DIR) -name "*.c" ! -name ilog2.c ! -name accept1.c ! -name connect1.c)
+TEST_SRC += $(TEST_MPIRPC_SRCS)
test/mpirpc-1/test%.x: test/mpirpc-1/test%.o $(CMPI)
$(Q) " MPICC $(@) "
Modified: branches/code/dense-1/test/mpirpc-2/module.mk.in
===================================================================
--- branches/code/dense-1/test/mpirpc-2/module.mk.in 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/test/mpirpc-2/module.mk.in 2009-04-30 22:49:07 UTC (rev 466)
@@ -3,8 +3,8 @@
ifeq (@USE_COMM_WORLD@,0)
-TEST_MPIRPC_SRCS += $(shell cd @SRC_ABSOLUTE_TOP@; find $(DIR) -name "*.c" )
-TEST_SRCS += $(TEST_MPIRPC_SRCS)
+TEST_MPIRPC_SRC += $(shell cd @SRC_ABSOLUTE_TOP@; find $(DIR) -name "*.c" )
+TEST_SRC += $(TEST_MPIRPC_SRCS)
test/mpirpc-2/test%.out: test/mpirpc-2/test%.x
$(LAUNCH) -n $(NODES) $(<) -c "reps=$(REPS)" > $(@) 2>&1
Modified: branches/code/dense-1/test/mpirpc-2/test01.c
===================================================================
--- branches/code/dense-1/test/mpirpc-2/test01.c 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/test/mpirpc-2/test01.c 2009-04-30 22:49:07 UTC (rev 466)
@@ -11,11 +11,12 @@
bool running = true;
void
-handle_ping(MPIRPC_Node caller, int unique, char* args)
+handle_ping(MPIRPC_Node caller, int unique, char* args,
+ char* blob, int blength)
{
NOTE_F;
SHOW_S(args);
- MPIRPC_Return(caller, unique, NULL);
+ MPIRPC_Null(caller, unique);
if (count++ < 3)
{
MPIRPC_Call(caller, "ping", NULL, NULL, MPIRPC_Free);
@@ -29,12 +30,13 @@
}
void
-handle_quit(MPIRPC_Node caller, int unique, char* args)
+handle_quit(MPIRPC_Node caller, int unique, char* args,
+ char* blob, int blength)
{
NOTE_F;
SHOW_S(args);
running = false;
- MPIRPC_Return(caller, unique, NULL);
+ MPIRPC_Null(caller);
}
int
Modified: branches/code/dense-1/test/paper1/module.mk.in
===================================================================
--- branches/code/dense-1/test/paper1/module.mk.in 2009-04-30 19:53:42 UTC (rev 465)
+++ branches/code/dense-1/test/paper1/module.mk.in 2009-04-30 22:49:07 UTC (rev 466)
@@ -6,9 +6,9 @@
# NODES is the number of nodes
# ARGS determines the length of tests that repeat operations
-TEST_PAPER1_SRCS = $(shell cd @SRC_ABSOLUTE_TOP@; find test/paper1 -name "*.c" ! -name test_helpers.c)
-TEST_SRCS += $(TEST_PAPER1_SRCS)
-TEST_HELPER_SRCS += test/paper1/test_helpers.c
+TEST_PAPER1_SRC = $(shell cd @SRC_ABSOLUTE_TOP@; find test/paper1 -name "*.c" ! -name test_helpers.c)
+TEST_SRC += $(TEST_PAPER1_SRCS)
+TEST_HELPER_SRC += test/paper1/test_helpers.c
# Max snooze time in milliseconds
ifeq ($(SNOOZE),)
1
0
Author: slang
Date: 2009-04-30 14:53:42 -0500 (Thu, 30 Apr 2009)
New Revision: 465
Modified:
trunk/code/src/gsl/common/gs.c
Log:
added check for resource that doesn't implement poll.
Modified: trunk/code/src/gsl/common/gs.c
===================================================================
--- trunk/code/src/gsl/common/gs.c 2009-04-30 15:09:51 UTC (rev 464)
+++ trunk/code/src/gsl/common/gs.c 2009-04-30 19:53:42 UTC (rev 465)
@@ -178,16 +178,34 @@
int gs_poll(gs_context_t context, int millisecs)
{
int resource_ms, i, ret;
+ int resources_polled = 0;
resource_ms = millisecs / context->resource_count;
for(i = 0; i < context->resource_count; ++i)
{
int rid = context->resource_ids[i];
- ret = gs_resource_entries[rid].resource->poll_context(context, resource_ms);
+ if(gs_resource_entries[rid].resource->poll_context)
+ {
+ ret = gs_resource_entries[rid].resource->poll_context(context, resource_ms);
+ if(ret != 0)
+ {
+ return ret;
+ }
+ resources_polled++;
+ }
+ }
+
+ if(resources_polled == 0)
+ {
+ struct timespec ts;
+
+ ts.tv_sec = (int)(millisecs / 1e3);
+ ts.tv_nsec = (millisecs % 1000) * 1e6;
+ ret = nanosleep(&ts, &rem);
if(ret != 0)
{
- return ret;
+ return -errno;
}
}
return 0;
1
0
Author: wozniak
Date: 2009-04-30 10:09:51 -0500 (Thu, 30 Apr 2009)
New Revision: 464
Added:
branches/code/dense-1/test/cmpi-cp/
Log:
Tests for cmpi-cp.
1
0
Author: slang
Date: 2009-04-29 22:18:29 -0500 (Wed, 29 Apr 2009)
New Revision: 463
Modified:
trunk/code/src/gsl/CGen.lhs
trunk/code/src/gsl/gs-parser
trunk/code/src/gsl/gs-parser.lhs
trunk/code/src/gsl/gscc
trunk/code/src/gsl/tests/correctness/btest-impl.c
trunk/code/src/gsl/tests/correctness/parallelfor.gs
Log:
fix parser from changes with state variables in pwait
Modified: trunk/code/src/gsl/CGen.lhs
===================================================================
--- trunk/code/src/gsl/CGen.lhs 2009-04-30 02:09:41 UTC (rev 462)
+++ trunk/code/src/gsl/CGen.lhs 2009-04-30 03:18:29 UTC (rev 463)
@@ -143,10 +143,9 @@
> mkStructDef :: Ident -> [CDecl] -> NodeInfo -> CTypeSpec
> mkStructDef name members ni = CSUType (CStruct CStructTag (Just name) (Just members) [] ni) ni
-> mkStructDefDecl :: String -> [CDecl] -> CDecl
-> mkStructDefDecl name members =
-> let ni = nodeInfo $ head members
-> in CDecl [CTypeSpec $ mkStructDef (newIdent name ni) members ni] [(Nothing, Nothing, Nothing)] ni
+> mkStructDefDecl :: String -> [CDecl] -> NodeInfo -> CDecl
+> mkStructDefDecl name members ni =
+> CDecl [CTypeSpec $ mkStructDef (newIdent name ni) members ni] [(Nothing, Nothing, Nothing)] ni
> mkStructDecl :: String -> String -> NodeInfo -> CDecl
> mkStructDecl tname name ni = mkCDecl (CSUType (CStruct CStructTag (Just $ newIdent tname ni)
@@ -178,8 +177,8 @@
genStructExtDecl "myStruct" [param1Decl, param2Decl]
-> genStructExtDecl :: String -> [CDecl] -> CExtDecl
-> genStructExtDecl name members = CDeclExt $ mkStructDefDecl name members
+> genStructExtDecl :: String -> [CDecl] -> NodeInfo -> CExtDecl
+> genStructExtDecl name members ni = CDeclExt $ mkStructDefDecl name members ni
Make a function pointer declarator: (*) (params);
Modified: trunk/code/src/gsl/gs-parser
===================================================================
(Binary files differ)
Modified: trunk/code/src/gsl/gs-parser.lhs
===================================================================
--- trunk/code/src/gsl/gs-parser.lhs 2009-04-30 02:09:41 UTC (rev 462)
+++ trunk/code/src/gsl/gs-parser.lhs 2009-04-30 03:18:29 UTC (rev 463)
@@ -395,25 +395,27 @@
> mkBlockingParamsStruct :: CFunDef -> WalkerT CExtDecl
> mkBlockingParamsStruct funDef = do
> let decls = getFunDefParams funDef
+> ni = nodeInfo funDef
> params = (map translateBlockingFunParam $ removeVoid decls) ++
> (map removeInitFromDecl $ getLocalDeclarations funDef)
-> return $ genStructExtDecl (mkStructParamsName $ getFunDefName funDef) params
+> return $ genStructExtDecl (mkStructParamsName $ getFunDefName funDef) params ni
> removeInits :: (String, [CDecl]) -> (String, [CDecl])
> removeInits (pwaitName, pwaitDecls) = (pwaitName, (map removeInitFromDecl pwaitDecls))
-> mkPWaitExtDecl :: String -> (String, [CDecl]) -> CExtDecl
-> mkPWaitExtDecl fname (pwaitName, pwaitDecls) =
-> genStructExtDecl (mkStructPWaitName fname pwaitName) pwaitDecls
+> mkPWaitExtDecl :: String -> (String, [CDecl]) -> NodeInfo -> CExtDecl
+> mkPWaitExtDecl fname (pwaitName, pwaitDecls) ni =
+> genStructExtDecl (mkStructPWaitName fname pwaitName) pwaitDecls ni
> mkBlockingPWaitStructs :: CFunDef -> BlockingContext -> WalkerT [CExtDecl]
> mkBlockingPWaitStructs funDef bctx
> | containsPWait bctx = do
> let fname = getFunDefName funDef
+> ni = nodeInfo funDef
> pwaits = getPWaits bctx
> pwaitDecls = zip (map getPWaitId pwaits) (map getPWaitDecls pwaits)
> params = map removeInits pwaitDecls
-> return $ map (mkPWaitExtDecl fname) params
+> return $ map (\p -> mkPWaitExtDecl fname p ni) params
> | otherwise = return []
@@ -435,7 +437,7 @@
> $ getPWaits bctx
> return $ genStructExtDecl ctlName
> (bparams ++ pparams ++
-> [fieldsDecl, paramsDecl] ++ pwaitDecls)
+> [fieldsDecl, paramsDecl] ++ pwaitDecls) ni
> mkPostFunName :: Bool -> String -> String -> String
> mkPostFunName True ctlName name = ctlName ++ "->" ++ name
Modified: trunk/code/src/gsl/gscc
===================================================================
--- trunk/code/src/gsl/gscc 2009-04-30 02:09:41 UTC (rev 462)
+++ trunk/code/src/gsl/gscc 2009-04-30 03:18:29 UTC (rev 463)
@@ -23,7 +23,7 @@
exit $res
fi
-${CC} -g -x c -c -o $gsfile.o $gsfile.i
+gcc -g -x c -c -o $gsfile.o $gsfile.i
res=$?
if test $res != 0; then
echo "compiling parsed $gsfile Failed!" 1>&2
Modified: trunk/code/src/gsl/tests/correctness/btest-impl.c
===================================================================
--- trunk/code/src/gsl/tests/correctness/btest-impl.c 2009-04-30 02:09:41 UTC (rev 462)
+++ trunk/code/src/gsl/tests/correctness/btest-impl.c 2009-04-30 03:18:29 UTC (rev 463)
@@ -6,25 +6,8 @@
#include "gs.h"
#include "gs-list.h"
-int btest_poll(gs_context_t ctx, int ms);
-int btest_cancel(gs_op_id_t id);
+static int btest_resource_id;
-static int btest_api_id;
-
-struct gs_api btest_api =
-{
- "btest",
- NULL,
- btest_poll,
- btest_cancel
-};
-
-int btest_init(void)
-{
- btest_api_id = gs_register_api(&btest_api);
- return 0;
-}
-
struct bsleep_op
{
void (*cb)(void *ptr, int ret);
@@ -57,7 +40,7 @@
assert(n);
n->cb = cb;
n->user_ptr = up;
- n->id = gs_id_gen(btest_api_id, (uint64_t)(uint32_t)n);
+ n->id = gs_id_gen(btest_resource_id, (uint64_t)(uint32_t)n);
n->value = v;
gs_list_add_tail(&n->link, list);
return n->id;
@@ -112,7 +95,7 @@
printf("BTEST SLEEP\n");
n->cb = callback;
n->user_ptr = up;
- n->id = gs_id_gen(btest_api_id, (uint64_t)(uint32_t)n);
+ n->id = gs_id_gen(btest_resource_id, (uint64_t)(uint32_t)n);
n->sleep = secs;
gs_list_add_tail(&n->link, &slist);
*op_id = n->id;
@@ -198,7 +181,7 @@
return 0;
}
-int btest_cancel(gs_op_id_t op_id)
+int btest_cancel(gs_context_t ctx, gs_op_id_t op_id)
{
struct gs_list_head *t, *tmp;
struct btest_op *b;
@@ -218,3 +201,17 @@
return 0;
}
+struct gs_resource btest_resource =
+{
+ .resource_name = "btest",
+ .poll_context = btest_poll,
+ .cancel = btest_cancel
+};
+
+int btest_init(void)
+{
+ btest_resource_id = gs_resource_register(&btest_resource);
+ return 0;
+}
+
+
Modified: trunk/code/src/gsl/tests/correctness/parallelfor.gs
===================================================================
--- trunk/code/src/gsl/tests/correctness/parallelfor.gs 2009-04-30 02:09:41 UTC (rev 462)
+++ trunk/code/src/gsl/tests/correctness/parallelfor.gs 2009-04-30 03:18:29 UTC (rev 463)
@@ -5,7 +5,7 @@
{
int a[100];
int ret[100];
- int i;
+ int i, j;
memset(a, 0, sizeof(int)*100);
memset(ret, 0, sizeof(int)*100);
@@ -14,15 +14,11 @@
{
pwait
{
- pcopy int i;
- pbranch {
- while(flow_buffer_not_done)
- {
for(i = 0; i < 100; ++i)
- {
+ {
pbranch
{
- int j = i;
+ j = i;
a[i] = i;
ret[i] = btest1(&a[i]);
assert(ret[i] == 0);
@@ -37,8 +33,9 @@
assert(ret[i] == 0);
assert(a[i] == (i+6));
}
- }
- }
+ }
+ }
+ }
printf("pwait done\n");
}
1
0
r462 - in trunk/code/src/gsl: . common resources/timer resources/timer/test
by slang@mcs.anl.gov 29 Apr '09
by slang@mcs.anl.gov 29 Apr '09
29 Apr '09
Author: slang
Date: 2009-04-29 21:09:41 -0500 (Wed, 29 Apr 2009)
New Revision: 462
Added:
trunk/code/src/gsl/resources/timer/test/
trunk/code/src/gsl/resources/timer/test/Makefile
trunk/code/src/gsl/resources/timer/test/timer1.gs
Modified:
trunk/code/src/gsl/common/Makefile
trunk/code/src/gsl/common/gs.c
trunk/code/src/gsl/gs-parser.lhs
trunk/code/src/gsl/resources/timer/gs-timer.c
Log:
working timer test.
Modified: trunk/code/src/gsl/common/Makefile
===================================================================
--- trunk/code/src/gsl/common/Makefile 2009-04-29 21:26:06 UTC (rev 461)
+++ trunk/code/src/gsl/common/Makefile 2009-04-30 02:09:41 UTC (rev 462)
@@ -1,6 +1,9 @@
all: gslib
+clean: ;
+ rm *.o *.a
+
gslib: libgs.a
libgs.a: gs.o gs-opcache.o
Modified: trunk/code/src/gsl/common/gs.c
===================================================================
--- trunk/code/src/gsl/common/gs.c 2009-04-29 21:26:06 UTC (rev 461)
+++ trunk/code/src/gsl/common/gs.c 2009-04-30 02:09:41 UTC (rev 462)
@@ -233,12 +233,15 @@
{
if(!strcmp(gs_resource_entries[j].resource->resource_name, rname))
{
- ret = gs_resource_entries[j].resource->register_context(c);
- if(ret != 0)
+ if(gs_resource_entries[j].resource->register_context)
{
- /* what do we do if a context fails to register with a resource? */
- va_end(ap);
- return ret;
+ ret = gs_resource_entries[j].resource->register_context(c);
+ if(ret != 0)
+ {
+ /* what do we do if a context fails to register with a resource? */
+ va_end(ap);
+ return ret;
+ }
}
c->resource_ids[rindex] = gs_resource_entries[j].id;
rindex++;
Modified: trunk/code/src/gsl/gs-parser.lhs
===================================================================
--- trunk/code/src/gsl/gs-parser.lhs 2009-04-29 21:26:06 UTC (rev 461)
+++ trunk/code/src/gsl/gs-parser.lhs 2009-04-30 02:09:41 UTC (rev 462)
@@ -39,7 +39,7 @@
> ([mkCDecl (CIntType ni) [] "__gs_cancel_ret" ni],
> [constructStmtFromC ni $ "child_ctl->parent->hit_pbreak = 1;",
> constructStmtFromC ni $ "gs_list_del(&child_ctl->link);",
-> constructStmtFromC ni $ "__gs_cancel_ret = gs_cancel_children(child_ctl->parent);"])
+> constructStmtFromC ni $ "__gs_cancel_ret = gs_cancel_children(child_ctl->context, child_ctl->parent);"])
After a blocking operation within a pbranch, we need to check if the pbranch has been cancelled,
either from a pbreak, or from an external cancel call of the entire blocking function.
Modified: trunk/code/src/gsl/resources/timer/gs-timer.c
===================================================================
--- trunk/code/src/gsl/resources/timer/gs-timer.c 2009-04-29 21:26:06 UTC (rev 461)
+++ trunk/code/src/gsl/resources/timer/gs-timer.c 2009-04-30 02:09:41 UTC (rev 462)
@@ -1,27 +1,28 @@
+#define _GNU_SOURCE
+
+#include <time.h>
+#include <sys/time.h>
+#include <errno.h>
+#include "gs.h"
+#include "gs-op.h"
+#include "gs-opcache.h"
+
#define TIMER_DEFAULT_SIZE 1024
static gs_opcache_t timer_opcache;
-static GS_LIST_HEAD(timer_list);
+static GS_LIST_HEAD(timer_oplist);
+static gs_mutex_t timer_mutex = GS_MUTEX_INITIALIZER;
+static int gs_timer_resource_id;
+
struct timer_op
{
- struct timeval;
- gs_op op;
+ struct timeval timer;
+ gs_op_id_t op_id;
+ struct gs_op op;
};
-int gs_timer_init(void)
-{
- ret = GS_OPCACHE_INIT(struct timer_op, op, TIMER_DEFAULT_SIZE, &timer_opcache);
- return ret;
-}
-
-int gs_timer_finalize(void)
-{
- gs_opcache_destroy(timer_opcache);
- return 0;
-}
-
int gs_timer_post(
int millisecs,
void (*callback)(void *ptr, int ret),
@@ -41,6 +42,7 @@
gs_op_fill(op, callback, user_ptr, hints, ctx);
top = gs_op_entry(op, struct timer_op, op);
+ top->op_id = gs_id_gen(gs_timer_resource_id, (uint64_t)(op->cache_id));
adjust.tv_sec = (int)(millisecs / 1e3);
adjust.tv_usec = (millisecs % 1000) * 1e3;
@@ -48,8 +50,8 @@
timeradd(&adjust, &now, &(top->timer));
gs_mutex_lock(&timer_mutex);
- holder = &timer_list;
- gs_list_for_each(iter, &timer_list)
+ holder = &timer_oplist;
+ gs_list_for_each(iter, &timer_oplist)
{
gs_op_iter = gs_list_get_entry(iter, struct gs_op, link);
timer_op_iter = gs_op_entry(gs_op_iter, struct timer_op, op);
@@ -60,23 +62,23 @@
}
holder = iter;
}
- gs_list_add(top, holder);
+ gs_list_add(&op->link, holder);
gs_mutex_unlock(&timer_mutex);
+ *op_id = top->op_id;
return 0;
-
}
-static int gs_mpi_poll(gs_context_t context, int millisecs)
+static int gs_timer_poll(gs_context_t context, int millisecs)
{
struct gs_list_head *entry;
struct gs_op *gop;
struct timer_op *top;
- struct timeval adjust, now, diff;
+ struct timeval adjust, now, diff, timeout;
struct timespec ts_diff, rem;
- int ret, ns_errno;
+ int ret;
gs_mutex_lock(&timer_mutex);
- entry = gs_list_peek(&timer_list);
+ entry = gs_list_peek(&timer_oplist);
if(entry)
{
gop = gs_list_get_entry(entry, struct gs_op, link);
@@ -92,7 +94,7 @@
/* what sort of errors could we return? */
/* this timer has hit, so we pop and call callback */
- entry = gs_list_pop(&timer_list);
+ entry = gs_list_pop(&timer_oplist);
gs_invoke_callback(gop, 0);
/* give the op back to the opcache */
@@ -100,7 +102,7 @@
gs_opcache_put(timer_opcache, gop);
/* setup for next iteration */
- entry = gs_list_peek(&timer_list);
+ entry = gs_list_peek(&timer_oplist);
if(entry)
{
gop = gs_list_get_entry(entry, struct gs_op, link);
@@ -112,7 +114,7 @@
adjust.tv_usec = (millisecs % 1000) * 1e3;
timeradd(&now, &adjust, &timeout);
- entry = gs_list_peek(&timer_list);
+ entry = gs_list_peek(&timer_oplist);
if(entry)
{
gop = gs_list_get_entry(entry, struct gs_op, link);
@@ -128,7 +130,7 @@
/* this timer will hit before the timeout is reached, so we pop, sleep,
* and call callback */
- entry = gs_list_pop(&timer_list);
+ entry = gs_list_pop(&timer_oplist);
ret = nanosleep(&ts_diff, &rem);
if(ret != 0)
{
@@ -137,12 +139,14 @@
return -EINTR;
}
+ gs_invoke_callback(gop, errno);
+
/* give the op back to the opcache */
gop = gs_list_get_entry(entry, struct gs_op, link);
gs_opcache_put(timer_opcache, gop);
/* setup for next iteration */
- entry = gs_list_peek(&timer_list);
+ entry = gs_list_peek(&timer_oplist);
if(entry)
{
gop = gs_list_get_entry(entry, struct gs_op, link);
@@ -161,18 +165,52 @@
return 0;
}
-static int gs_timer_cancel(gs_op_id_t op_id)
+static int gs_timer_cancel(gs_context_t gs_ctx, gs_op_id_t op_id)
{
+ int cache_id, resource_id;
+ gs_mutex_lock(&timer_mutex);
+ struct gs_op *op;
+ struct timer_op *top;
+
+ cache_id = gs_id_lookup(op_id, &resource_id);
+ assert(resource_id == gs_timer_resource_id);
+
+ op = gs_opcache_lookup(timer_opcache, (int)cache_id);
+ top = gs_op_entry(op, struct timer_op, op);
+ gs_list_del(&op->link);
+ gs_opcache_put(timer_opcache, op);
+
+ gs_mutex_unlock(&timer_mutex);
+
+ return 0;
}
-struct gs_api gs_mpi_api =
+struct gs_resource gs_timer_resource =
{
- "timer",
- NULL,
- gs_timer_poll,
- gs_timer_cancel
+ .resource_name = "timer",
+ .poll_context = gs_timer_poll,
+ .cancel = gs_timer_cancel
};
+int gs_timer_init(void)
+{
+ int ret;
+
+ ret = GS_OPCACHE_INIT(struct timer_op, op, TIMER_DEFAULT_SIZE, &timer_opcache);
+
+ gs_timer_resource_id = gs_resource_register(&gs_timer_resource);
+
+ return ret;
+}
+
+int gs_timer_finalize(void)
+{
+ gs_resource_unregister(gs_timer_resource_id);
+
+ gs_opcache_destroy(timer_opcache);
+ return 0;
+}
+
/*
* Local variables:
* c-indent-level: 4
Added: trunk/code/src/gsl/resources/timer/test/Makefile
===================================================================
--- trunk/code/src/gsl/resources/timer/test/Makefile (rev 0)
+++ trunk/code/src/gsl/resources/timer/test/Makefile 2009-04-30 02:09:41 UTC (rev 462)
@@ -0,0 +1,28 @@
+
+GS=../../..
+
+gsfiles=timer1.gs
+
+tests=$(patsubst %.gs,%,$(gsfiles))
+objs=$(patsubst %.gs,%.gs.o,$(gsfiles))
+cpps=$(patsubst %.gs,%.gs.gsi,$(gsfiles))
+trans=$(patsubst %.gs,%.gs.i,$(gsfiles))
+
+all: $(tests)
+
+clean: ;
+ rm -f $(objs) $(tests) $(trans) $(cpps)
+
+%.gs: ;
+
+$(cpps): %.gs.gsi: %.gs
+ $(CC) -I.. -I${GS}/include -x c -E $< -o $@
+
+$(trans): %.gs.i: %.gs.gsi
+ ${GS}/gs-parser -p $< > $@
+
+$(objs): %.gs.o: %.gs.i
+ $(CC) -g -x c -c -o $@ $<
+
+$(tests): %: %.gs.o
+ $(CC) -o $@ $< ../gs-timer.o -L${GS}/common -lgs
Added: trunk/code/src/gsl/resources/timer/test/timer1.gs
===================================================================
--- trunk/code/src/gsl/resources/timer/test/timer1.gs (rev 0)
+++ trunk/code/src/gsl/resources/timer/test/timer1.gs 2009-04-30 02:09:41 UTC (rev 462)
@@ -0,0 +1,67 @@
+
+#include <stdio.h>
+#include "gs.h"
+#include "gs-timer.gsh"
+
+__blocking int dotimer(void)
+{
+ pwait
+ {
+ pbranch
+ {
+ printf("sleeping for 100 ms\n");
+ gs_timer(100);
+ printf("100 ms done.\n");
+ }
+
+ pbranch
+ {
+ printf("sleeping for 1000 ms\n");
+ gs_timer(1000);
+ printf("1000 ms done.\n");
+ }
+
+ pbranch
+ {
+ printf("sleeping for 10 ms\n");
+ gs_timer(10);
+ printf("10 ms done.\n");
+ }
+ }
+ return 0;
+}
+
+int done = 0;
+
+void done_callback(void *up, int ret)
+{
+ done = 1;
+}
+
+int main(int argc, char *argv[])
+{
+ gs_context_t ctx;
+ int pc = 0;
+ gs_op_id_t op_id;
+
+ gs_timer_init();
+ gs_context_create(&ctx, 1, "timer");
+
+ dotimer_post(done_callback, NULL, NULL, ctx, &op_id);
+ while(done == 0)
+ {
+ gs_poll(ctx, 10);
+ printf("polled %d times\n", ++pc);
+ }
+
+ return 0;
+}
+
+/*
+ * Local variables:
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * End:
+ *
+ * vim: ts=8 sts=4 sw=4 expandtab
+ */
1
0
r461 - in trunk/code/src/gsl: . common include resources/mpi resources/mpi/test
by slang@mcs.anl.gov 29 Apr '09
by slang@mcs.anl.gov 29 Apr '09
29 Apr '09
Author: slang
Date: 2009-04-29 16:26:06 -0500 (Wed, 29 Apr 2009)
New Revision: 461
Modified:
trunk/code/src/gsl/common/gs.c
trunk/code/src/gsl/gs-parser
trunk/code/src/gsl/gs-parser.lhs
trunk/code/src/gsl/include/gs-hash.h
trunk/code/src/gsl/include/gs-op.h
trunk/code/src/gsl/include/gs-opcache.h
trunk/code/src/gsl/include/gs.h
trunk/code/src/gsl/resources/mpi/gs-mpi.c
trunk/code/src/gsl/resources/mpi/gs-mpi.gsh
trunk/code/src/gsl/resources/mpi/test/send-recv.gs
Log:
a bunch of changes.
Modified: trunk/code/src/gsl/common/gs.c
===================================================================
--- trunk/code/src/gsl/common/gs.c 2009-04-29 20:39:30 UTC (rev 460)
+++ trunk/code/src/gsl/common/gs.c 2009-04-29 21:26:06 UTC (rev 461)
@@ -5,46 +5,65 @@
struct gs_resource_entry
{
int id;
- struct gs_resource resource;
+ struct gs_resource *resource;
};
static int gs_resource_count = 0;
static struct gs_resource_entry gs_resource_entries[GS_MAX_RESOURCES];
-int gs_register_resource(struct gs_resource *resource)
+
+struct gs_context
{
+ int id;
+ int resource_count;
+ int *resource_ids;
+};
+
+static int gs_context_count = 0;
+static struct gs_context gs_context_entries[GS_MAX_CONTEXTS];
+
+int gs_resource_register(struct gs_resource *resource)
+{
int index = gs_resource_count;
- if(gs_resource_count == GS_MAX_APIS)
+ if(gs_resource_count == GS_MAX_RESOURCES)
{
return -EINVAL;
}
-
- gs_api_entries[index].id = gs_api_count;
- gs_api_entries[index].api.api_name = api->api_name;
- gs_api_entries[index].api.test = api->test;
- gs_api_entries[index].api.poll_context = api->poll_context;
- gs_api_entries[index].api.cancel = api->cancel;
- gs_api_count++;
+ gs_resource_entries[index].id = gs_resource_count;
+ gs_resource_entries[index].resource = resource;
+ gs_resource_count++;
return index;
}
-int gs_cancel_op(gs_op_id_t op_id)
+int gs_resource_unregister(int id)
{
+ gs_resource_entries[id].id = -1;
+ gs_resource_entries[id].resource = NULL;
+}
+
+int gs_cancel_op(gs_context_t context, gs_op_id_t op_id)
+{
struct gs_ctl *ctl;
- int api_id;
+ int resource_id;
int ret = -EINVAL;
- gs_id_lookup(op_id, &api_id);
- if(api_id > gs_api_count)
+ gs_id_lookup(op_id, &resource_id);
+ if(resource_id > gs_resource_count)
{
gs_mutex_unlock(&ctl->mutex);
return -EINVAL;
}
- if(api_id == 0)
+ if(gs_resource_entries[resource_id].id == -1)
{
+ gs_mutex_unlock(&ctl->mutex);
+ return -EINVAL;
+ }
+
+ if(resource_id == 0)
+ {
ctl = (struct gs_ctl *)(intptr_t)gs_id_lookup(op_id, NULL);
gs_mutex_lock(&ctl->mutex);
if(ctl->cancelled)
@@ -68,7 +87,7 @@
gs_list_for_each(entry, &ctl->children)
{
child_ctl = gs_list_get_entry(entry, typeof(*child_ctl), link);
- ret = gs_cancel_op(child_ctl->current_op_id);
+ ret = gs_cancel_op(context, child_ctl->current_op_id);
if(ret != 0)
{
/* cancel failed */
@@ -78,29 +97,29 @@
}
else
{
- ret = gs_cancel_op(ctl->current_op_id);
+ ret = gs_cancel_op(context, ctl->current_op_id);
}
gs_mutex_unlock(&ctl->mutex);
return ret;
}
- ret = gs_api_entries[api_id].api.cancel(op_id);
+ ret = gs_resource_entries[resource_id].resource->cancel(context, op_id);
gs_mutex_unlock(&ctl->mutex);
return ret;
}
-gs_op_id_t gs_id_gen(int api_id, uint64_t ptr)
+gs_op_id_t gs_id_gen(int resource_id, uint64_t ptr)
{
- return (gs_op_id_t)(GS_GET_API_MASK(api_id) | ptr);
+ return (gs_op_id_t)(GS_GET_RESOURCE_MASK(resource_id) | ptr);
}
-uint64_t gs_id_lookup(gs_op_id_t id, int *api_id)
+uint64_t gs_id_lookup(gs_op_id_t id, int *resource_id)
{
- if(api_id) *api_id = GS_GET_API_ID(id);
- return (~GS_API_MASK)&id;
+ if(resource_id) *resource_id = GS_GET_RESOURCE_ID(id);
+ return (~GS_RESOURCE_MASK)&id;
}
-int gs_cancel_children(void *ptr)
+int gs_cancel_children(gs_context_t context, void *ptr)
{
int ret;
struct gs_ctl *ctl;
@@ -116,7 +135,7 @@
gs_list_for_each(entry, &ctl->children)
{
child_ctl = gs_list_get_entry(entry, typeof(*child_ctl), link);
- ret = gs_cancel_op(child_ctl->current_op_id);
+ ret = gs_cancel_op(context, child_ctl->current_op_id);
if(ret != 0)
{
/* cancel failed */
@@ -160,11 +179,12 @@
{
int resource_ms, i, ret;
- resource_ms = millisecs / gs_api_count;
+ resource_ms = millisecs / context->resource_count;
- for(i = 0; i < gs_resource_count; ++i)
+ for(i = 0; i < context->resource_count; ++i)
{
- ret = gs_resource_entries[i].api.poll_context(context, resource_ms);
+ int rid = context->resource_ids[i];
+ ret = gs_resource_entries[rid].resource->poll_context(context, resource_ms);
if(ret != 0)
{
return ret;
@@ -173,4 +193,68 @@
return 0;
}
-int gs_context_create(gs_context_t *context,
+#include <stdarg.h>
+
+int gs_context_create(gs_context_t *context, int resource_count, ...)
+{
+ va_list ap;
+ char *rname;
+ int index = gs_context_count;
+ gs_context_t c;
+ int i, j, ret, rindex;
+
+ if(gs_context_count == GS_MAX_CONTEXTS)
+ {
+ return -EINVAL;
+ }
+
+ c = &(gs_context_entries[index]);
+ c->id = gs_context_count;
+ gs_context_count++;
+ c->resource_count = resource_count;
+ c->resource_ids = malloc(sizeof(int) * resource_count);
+ if(!c->resource_ids)
+ {
+ return -ENOMEM;
+ }
+ rindex = 0;
+
+
+ /* step through the resource names passed in and register the context with them */
+ va_start(ap, resource_count);
+ for(i = 0; i < resource_count; ++i)
+ {
+ int resource_found = 0;
+ rname = va_arg(ap, char *);
+
+ /* find the matching resource and register the context with that resource */
+
+ for(j = 0; j < gs_resource_count; ++j)
+ {
+ if(!strcmp(gs_resource_entries[j].resource->resource_name, rname))
+ {
+ ret = gs_resource_entries[j].resource->register_context(c);
+ if(ret != 0)
+ {
+ /* what do we do if a context fails to register with a resource? */
+ va_end(ap);
+ return ret;
+ }
+ c->resource_ids[rindex] = gs_resource_entries[j].id;
+ rindex++;
+ resource_found = 1;
+ break;
+ }
+ }
+ if(!resource_found)
+ {
+ va_end(ap);
+ return -EINVAL;
+ }
+ }
+ va_end(ap);
+
+ *context = c;
+ return 0;
+}
+
Modified: trunk/code/src/gsl/gs-parser
===================================================================
(Binary files differ)
Modified: trunk/code/src/gsl/gs-parser.lhs
===================================================================
--- trunk/code/src/gsl/gs-parser.lhs 2009-04-29 20:39:30 UTC (rev 460)
+++ trunk/code/src/gsl/gs-parser.lhs 2009-04-29 21:26:06 UTC (rev 461)
@@ -112,6 +112,8 @@
> [constructDeclFromC ni ("struct " ++ (mkStructCtlName fname) ++ " *" ++ prefix ++ ";")]
> ([constructStmtFromC ni $ prefix ++ " = malloc(sizeof(*" ++ prefix ++ "));",
> constructStmtFromC ni $ prefix ++ "->parent = " ++ parentPrefix ++ ";",
+> constructStmtFromC ni $ prefix++"->context = "++parentPrefix++"->context;",
+> constructStmtFromC ni $ prefix++"->hints = "++parentPrefix++"->hints;",
> constructStmtFromC ni $ prefix++"->params = "++parentPrefix++"->params;",
> constructStmtFromC ni $ "memcpy(&"++prefix++"->"++pwaitName++",&"++parentPrefix++"->"++pwaitName++", sizeof("++prefix++"->"++pwaitName++"));",
> constructStmtFromC ni $ "gs_mutex_lock(&("++prefix++"->parent->mutex));"]
Modified: trunk/code/src/gsl/include/gs-hash.h
===================================================================
--- trunk/code/src/gsl/include/gs-hash.h 2009-04-29 20:39:30 UTC (rev 460)
+++ trunk/code/src/gsl/include/gs-hash.h 2009-04-29 21:26:06 UTC (rev 461)
@@ -12,6 +12,7 @@
#include "gs.h"
#define gs_hash_head gs_list_head
+#define gs_hash_get_entry gs_list_get_entry
struct gs_hash_table
{
@@ -249,7 +250,7 @@
gs_list_for_each_safe(entry, tmpe, &(_oldtable->array[i])) \
{ \
gs_list_del(entry); \
- _destructor(gs_hash_entry(entry, _entry_type, _link)); \
+ _destructor(gs_hash_get_entry(entry, _entry_type, _link)); \
} \
} \
gs_mutex_unlock(&_oldtable->lock); \
Modified: trunk/code/src/gsl/include/gs-op.h
===================================================================
--- trunk/code/src/gsl/include/gs-op.h 2009-04-29 20:39:30 UTC (rev 460)
+++ trunk/code/src/gsl/include/gs-op.h 2009-04-29 21:26:06 UTC (rev 461)
@@ -1,6 +1,6 @@
-#ifndef __GS_OPCACHE_H__
-#define __GS_OPCACHE_H__
+#ifndef __GS_OP_H__
+#define __GS_OP_H__
#include "gs.h"
Modified: trunk/code/src/gsl/include/gs-opcache.h
===================================================================
--- trunk/code/src/gsl/include/gs-opcache.h 2009-04-29 20:39:30 UTC (rev 460)
+++ trunk/code/src/gsl/include/gs-opcache.h 2009-04-29 21:26:06 UTC (rev 461)
@@ -5,17 +5,6 @@
#include "gs.h"
#include "gs-op.h"
-struct gs_op
-{
- int index;
- void (*callback)(void *ptr, int ret);
- void *user_ptr;
- gs_hints_t hints;
- gs_context_t ctx;
- gs_op_id_t id;
- struct gs_list_head link;
-};
-
typedef struct gs_opcache *gs_opcache_t;
#define gs_op_entry(_op, _type, _member) \
Modified: trunk/code/src/gsl/include/gs.h
===================================================================
--- trunk/code/src/gsl/include/gs.h 2009-04-29 20:39:30 UTC (rev 460)
+++ trunk/code/src/gsl/include/gs.h 2009-04-29 21:26:06 UTC (rev 461)
@@ -10,10 +10,11 @@
#define GS_ECANCELLED (GS_ERR_MASK | 1)
#define GS_MAX_RESOURCES 255
+#define GS_MAX_CONTEXTS 1024
-#define GS_API_MASK (((uint64_t)0xFF)<<56)
-#define GS_GET_API_MASK(resource_id) (GS_API_MASK&(((uint64_t)resource_id)<<56))
-#define GS_GET_API_ID(op_id) (((op_id&GS_API_MASK)>>56)&0xFF)
+#define GS_RESOURCE_MASK (((uint64_t)0xFF)<<56)
+#define GS_GET_RESOURCE_MASK(resource_id) (GS_RESOURCE_MASK&(((uint64_t)resource_id)<<56))
+#define GS_GET_RESOURCE_ID(op_id) (((op_id&GS_RESOURCE_MASK)>>56)&0xFF)
#ifdef __GS_POSIX_LOCKING__
#include <pthread.h>
@@ -70,40 +71,36 @@
#endif
-struct gs_ctl
-{
- gs_op_id_t current_op_id;
- int cancelled;
- gs_mutex_t mutex;
- struct gs_list_head children;
- struct gs_list_head link;
- int posted;
- int completed;
- int allposted;
- int hit_pbreak;
- int in_pwait;
-};
-
+/* The resource structure is defined by a given resource, and registered
+ * to the gs management code during resource initialization.
+ */
struct gs_resource
{
char *resource_name;
int (*test)(gs_op_id_t id, int ms_timeout);
int (*poll_context)(gs_context_t context, int ms_timeout);
- int (*cancel)(gs_op_id_t id);
+ int (*cancel)(gs_context_t ctx, gs_op_id_t id);
int (*register_context)(gs_context_t context);
+ int (*unregister_context)(gs_context_t context);
};
-int gs_register_resource(struct gs_resource *resource);
+/* Called by resources to register themselves to the resource framework */
+int gs_resource_register(struct gs_resource *resource);
+int gs_resource_unregister(int resource_id);
-int gs_cancel_op(gs_op_id_t op_id);
+/* Contexts are created to allow separation of polling for different logical
+ * groups of operations.
+ */
+int gs_context_create(gs_context_t *context, int resource_count, ...);
-/* internal function -- used by generated code */
-int gs_cancel_children(void *ptr);
+/* Poll for completion of the operations within the given context up to a
+ * timeout value.
+ */
+int gs_poll(gs_context_t context, int ms);
-void gs_assert(const char *str, int expr);
+/* Cancel an operation */
+int gs_cancel_op(gs_context_t context, gs_op_id_t op_id);
-int gs_poll(gs_context_t context, int ms);
-
#include <sys/time.h>
#define GS_REL_MSECS_TO_ABS_TIMESPEC(__msecs, __abs) \
@@ -119,4 +116,29 @@
} \
} while(0)
+/* The gs_ctl structure is used by the gsl generated code to manage parallel and
+ * nested operations. This structure is not needed by resource writers or gsl
+ * code.
+ * TODO: move these to a separate header
+ */
+struct gs_ctl
+{
+ gs_op_id_t current_op_id;
+ int cancelled;
+ gs_mutex_t mutex;
+ struct gs_list_head children;
+ struct gs_list_head link;
+ int posted;
+ int completed;
+ int allposted;
+ int hit_pbreak;
+ int in_pwait;
+};
+
+/* internal function -- used by generated code */
+int gs_cancel_children(gs_context_t ctx, void *ptr);
+
+/* internal function -- used by generated code */
+void gs_assert(const char *str, int expr);
+
#endif
Modified: trunk/code/src/gsl/resources/mpi/gs-mpi.c
===================================================================
--- trunk/code/src/gsl/resources/mpi/gs-mpi.c 2009-04-29 20:39:30 UTC (rev 460)
+++ trunk/code/src/gsl/resources/mpi/gs-mpi.c 2009-04-29 21:26:06 UTC (rev 461)
@@ -16,165 +16,152 @@
struct gs_op op;
};
-static gs_opcache_t mpi_opcache;
-static GS_LIST_HEAD(mpi_oplist);
-static gs_mutex_t oplist_mutex = GS_MUTEX_INITIALIZER;
+struct mpi_context
+{
+ gs_context_t gs_ctx_ptr;
-static MPI_Request *reqarray;
-static int *indexarray;
-static MPI_Status *statusarray;
-static int array_size = MPI_TESTCOUNT_MAXSIZE;
-static int array_count = 0;
-static gs_mutex_t array_mutex = GS_MUTEX_INITIALIZER;
+ gs_opcache_t opcache;
+ struct gs_list_head oplist;
+ gs_mutex_t oplist_mutex;
-static gs_mutex_t wait_mutex = GS_MUTEX_INITIALIZER;
-static gs_cond_t wait_cond;
+ MPI_Request *reqarray;
+ MPI_Status *statusarray;
+ int *indexarray;
-static int gs_mpi_id;
+ int array_size;
+ int array_count;
+ gs_mutex_t array_mutex;
-static int ops_in_progress = 0;
+ gs_mutex_t wait_mutex;
+ gs_cond_t wait_cond;
-static int mpi_initialized = 0;
+ int ops_in_progress;
-struct gs_api gs_mpi_api;
+ struct gs_hash_head link;
+};
-int gs_mpi_init(void)
-{
- int ret;
+static struct gs_hash_table *context_table;
+static gs_mutex_t ctx_mutex;
- ret = GS_OPCACHE_INIT(struct mpi_op, op, array_size, &mpi_opcache);
- if(ret != 0)
- {
- return ret;
- }
+static int gs_mpi_resource_id;
- reqarray = malloc(sizeof(*reqarray) * array_size);
- if(!reqarray)
+static int mpi_initialized = 0;
+
+static int double_array_size(struct mpi_context *ctx)
+{
+ gs_mutex_lock(&ctx->array_mutex);
+ ctx->array_size *= 2;
+ ctx->reqarray = realloc(ctx->reqarray, sizeof(*ctx->reqarray) * ctx->array_size);
+ if(!ctx->reqarray)
{
- gs_opcache_destroy(mpi_opcache);
- return -ENOMEM;
+ gs_mutex_unlock(&ctx->array_mutex);
+ return -ENOMEM;
}
- indexarray = malloc(sizeof(*indexarray) * array_size);
- if(!indexarray)
+ ctx->indexarray = realloc(ctx->indexarray, sizeof(*ctx->indexarray) * ctx->array_size);
+ if(!ctx->indexarray)
{
- gs_opcache_destroy(mpi_opcache);
- free(reqarray);
+ gs_mutex_unlock(&ctx->array_mutex);
return -ENOMEM;
}
-
- statusarray = malloc(sizeof(*statusarray) * array_size);
- if(!statusarray)
+ ctx->statusarray = realloc(ctx->statusarray, sizeof(*ctx->statusarray) * ctx->array_size);
+ if(!ctx->statusarray)
{
- free(indexarray);
- gs_opcache_destroy(mpi_opcache);
- free(reqarray);
+ gs_mutex_unlock(&ctx->array_mutex);
return -ENOMEM;
}
-
- gs_cond_init(&wait_cond, NULL);
-
- gs_mpi_id = gs_register_api(&gs_mpi_api);
-
- mpi_initialized = 1;
-
+ gs_mutex_unlock(&ctx->array_mutex);
return 0;
}
-int gs_mpi_finalize(void)
+static int add_op(MPI_Request req,
+ MPI_Status *status,
+ void (*callback)(void *ptr, int ret),
+ void *up,
+ gs_hints_t hints,
+ gs_context_t gs_ctx,
+ gs_op_id_t *op_id)
{
- struct gs_op *op, *tmp;
struct mpi_op *mpi_op;
+ struct gs_op *op;
+ struct gs_hash_head *link;
+ struct mpi_context *ctx;
- mpi_initialized = 0;
-
- gs_mutex_lock(&oplist_mutex);
- /* we need to cancel and cleanup all pending MPI operations */
- gs_list_for_each_entry_safe(op, tmp, &mpi_oplist, link)
+ /* get the mpi context structure from the context hashtable */
+ link = gs_hash_search(context_table, gs_ctx);
+ if(!link)
{
- mpi_op = gs_op_entry(op, struct mpi_op, op);
- ret = MPI_Cancel(mpi_op->request);
- if(ret == MPI_ERR_REQUEST || ret == MPI_ERR_ARG)
- {
- gs_mutex_unlock(&oplist_mutex);
- return -EINVAL;
- }
+ return -EINVAL;
}
+ ctx = gs_hash_get_entry(link, struct mpi_context, link);
- while(!gs_list_empty(&mpi_oplist))
+ op = gs_opcache_get(ctx->opcache);
+
+ /* kind of a hack for mpi case, if size of opcache doubles, we double
+ * the request and index arrays too
+ */
+ if(gs_opcache_size(ctx->opcache) > ctx->array_size)
{
- gs_mpi_poll(
+ double_array_size(ctx);
+ }
+ mpi_op = gs_op_entry(op, struct mpi_op, op);
+ mpi_op->status = status;
- gs_mutex_unlock(&oplist_mutex);
+ gs_op_fill(op, callback, up, hints, gs_ctx);
-
- free(reqarray);
- free(indexarray);
- free(statusarray);
- gs_opcache_destroy(mpi_opcache);
+ mpi_op->op_id = gs_id_gen(gs_mpi_resource_id, (uint64_t)(op->cache_id));
+ ctx->reqarray[op->cache_id] = req;
+ mpi_op->request = &(ctx->reqarray[op->cache_id]);
+ gs_mutex_lock(&ctx->oplist_mutex);
+ gs_list_add(&op->link, &ctx->oplist);
+ gs_mutex_unlock(&ctx->oplist_mutex);
+ *op_id = mpi_op->op_id;
return 0;
}
-static int double_array_size(void)
+static int remove_op(struct mpi_context *ctx, gs_op_id_t id)
{
- gs_mutex_lock(&array_mutex);
- array_size *= 2;
- reqarray = realloc(reqarray, sizeof(*reqarray) * array_size);
- if(!reqarray)
- {
- gs_mutex_unlock(&array_mutex);
- return -ENOMEM;
- }
+ int cache_id, resource_id;
+ struct gs_op *op;
- indexarray = realloc(indexarray, sizeof(*indexarray) * array_size);
- if(!indexarray)
- {
- gs_mutex_unlock(&array_mutex);
- return -ENOMEM;
- }
- statusarray = realloc(statusarray, sizeof(*statusarray) * array_size);
- if(!statusarray)
- {
- gs_mutex_unlock(&array_mutex);
- return -ENOMEM;
- }
- gs_mutex_unlock(&array_mutex);
+ cache_id = gs_id_lookup(id, &resource_id);
+ op = gs_opcache_lookup(ctx->opcache, cache_id);
+
+ /* remove the op from the operation list */
+ gs_mutex_lock(&ctx->oplist_mutex);
+ gs_list_del(&op->link);
+ gs_mutex_unlock(&ctx->oplist_mutex);
+
+ /* give the op back to the opcache */
+ gs_opcache_put(ctx->opcache, op);
return 0;
}
-static int add_op(MPI_Request req,
- MPI_Status *status,
- void (*callback)(void *ptr, int ret),
- void *up,
- gs_hints_t hints,
- gs_context_t ctx)
+static int set_ops_in_progress(gs_context_t gs_ctx)
{
- struct mpi_op *mpi_op;
- struct gs_op *op;
+ struct gs_hash_head *link;
+ struct mpi_context *ctx;
- op = gs_opcache_get(mpi_opcache);
+ link = gs_hash_search(context_table, gs_ctx);
+ if(!link)
+ {
+ return -EINVAL;
+ }
+ ctx = gs_hash_get_entry(link, struct mpi_context, link);
- /* kind of a hack for mpi case, if size of opcache doubles, we double
- * the request and index arrays too
+ /* if no ops in progress, the poll function may be sleeping, so we
+ * send a signal to wake it up and test
*/
- if(gs_opcache_size(mpi_opcache) > array_size)
+ if(ctx->ops_in_progress == 0)
{
- double_array_size();
+ gs_mutex_lock(&ctx->wait_mutex);
+ ctx->ops_in_progress = 1;
+ gs_cond_signal(&ctx->wait_cond);
+ gs_mutex_unlock(&ctx->wait_mutex);
}
- mpi_op = gs_op_entry(op, struct mpi_op, op);
- mpi_op->status = status;
-
- gs_op_fill(op, callback, up, hints, ctx);
-
- mpi_op->op_id = gs_id_gen(gs_mpi_id, (uint64_t)(op->cache_id));
- reqarray[op->cache_id] = req;
- mpi_op->request = &(reqarray[op->cache_id]);
- gs_mutex_lock(&oplist_mutex);
- gs_list_add(&op->link, &mpi_oplist);
- gs_mutex_unlock(&oplist_mutex);
- return mpi_op->op_id;
+ return 0;
}
#define DEFINE_MPISEND_CALL(__CALL__) \
@@ -197,7 +184,7 @@
if(!mpi_initialized) \
{ \
callback(user_ptr, -GS_ECANCELLED); \
- return GS_COMPLETED; \
+ return GS_COMPLETE; \
} \
\
ret = MPI_I##__CALL__( \
@@ -211,17 +198,18 @@
if(ret != MPI_SUCCESS) \
{ \
callback(user_ptr, ret); \
- return GS_COMPLETED; \
+ return GS_COMPLETE; \
} \
\
- *op_id = add_op(request, NULL, callback, user_ptr, hints, ctx); \
- if(ops_in_progress == 0) \
+ /* status is null for send calls */ \
+ ret = add_op(request, NULL, callback, user_ptr, hints, ctx, op_id); \
+ if(ret != 0) \
{ \
- gs_mutex_lock(&wait_mutex); \
- ops_in_progress = 1; \
- gs_cond_signal(&wait_cond); \
- gs_mutex_unlock(&wait_mutex); \
+ callback(user_ptr, ret); \
+ return GS_COMPLETE; \
} \
+ \
+ set_ops_in_progress(ctx); \
return GS_POSTED; \
}
@@ -241,7 +229,7 @@
void (*callback)(void *ptr, int ret),
void *user_ptr,
gs_hints_t hints,
- gs_context_t ctx,
+ gs_context_t gs_ctx,
gs_op_id_t *op_id)
{
int ret;
@@ -254,28 +242,41 @@
return GS_POSTED;
}
- *op_id = add_op(request, status, callback, user_ptr, hints, ctx);
- if(ops_in_progress == 0)
+ ret = add_op(request, NULL, callback, user_ptr, hints, gs_ctx, op_id);
+ if(ret != 0)
{
- gs_mutex_lock(&wait_mutex);
- ops_in_progress = 1;
- gs_cond_signal(&wait_cond);
- gs_mutex_unlock(&wait_mutex);
+ callback(user_ptr, ret);
+ return GS_COMPLETE;
}
+
+ set_ops_in_progress(gs_ctx);
return GS_POSTED;
}
-static int gs_mpi_poll(gs_context_t context, int millisecs)
+static int gs_mpi_poll(gs_context_t gs_ctx, int millisecs)
{
int ret, outcount, test_count;
struct timespec t;
struct gs_op *op;
struct mpi_op *mpi_op;
+ struct mpi_context *ctx;
+ struct gs_hash_head *link;
- test_count = gs_opcache_count(mpi_opcache);
+ /* get the mpi context structure from the context hashtable */
+ gs_mutex_lock(&ctx_mutex);
+ link = gs_hash_search(context_table, gs_ctx);
+ gs_mutex_unlock(&ctx_mutex);
+ if(!link)
+ {
+ return -EINVAL;
+ }
+ ctx = gs_hash_get_entry(link, struct mpi_context, link);
+ test_count = gs_opcache_count(ctx->opcache);
+
/* Wait for completion of operations */
- ret = MPI_Waitsome(test_count, reqarray, &outcount, indexarray, statusarray);
+ ret = MPI_Waitsome(
+ test_count, ctx->reqarray, &outcount, ctx->indexarray, ctx->statusarray);
/* According to MPI spec, if all requests in reqarray are null, outcount is
* set to MPI_UNDEFINED. This happens every time we poll without any operations
@@ -284,32 +285,38 @@
*/
if(outcount == MPI_UNDEFINED)
{
- gs_mutex_lock(&wait_mutex);
+ gs_mutex_lock(&ctx->wait_mutex);
/* Verify that no ops are posted with lock held. This prevents us from missing
- * a signal from a post.
+ * a signal from a post. We test on the entire request array (most will be
+ * MPI_REQUEST_NULL), just so that we don't miss a request getting added after
+ * we got the test_count field from the opcache.
*/
- ret = MPI_Waitsome(array_count, reqarray, &outcount, indexarray, statusarray);
+ ret = MPI_Waitsome(
+ ctx->array_size, ctx->reqarray, &outcount, ctx->indexarray, ctx->statusarray);
if(outcount == MPI_UNDEFINED)
{
/* ok, no ops posted, so we can wait */
- ops_in_progress = 0;
+ ctx->ops_in_progress = 0;
/* timedwait takes absolute time */
GS_REL_MSECS_TO_ABS_TIMESPEC(millisecs, t);
- ret = gs_cond_timedwait(&wait_cond, &wait_mutex, &t);
+ ret = gs_cond_timedwait(&ctx->wait_cond, &ctx->wait_mutex, &t);
if(ret != 0)
{
/* we assume timedout or was interrupted by a signal */
- gs_mutex_unlock(&wait_mutex);
+ gs_mutex_unlock(&ctx->wait_mutex);
return ret;
}
+ test_count = gs_opcache_count(ctx->opcache);
+
/* we're here so ops are in progress and we must test for completion */
- ret = MPI_Waitsome(array_count, reqarray, &outcount, indexarray, statusarray);
+ ret = MPI_Waitsome(
+ test_count, ctx->reqarray, &outcount, ctx->indexarray, ctx->statusarray);
assert(outcount != MPI_UNDEFINED);
}
- gs_mutex_unlock(&wait_mutex);
+ gs_mutex_unlock(&ctx->wait_mutex);
}
if(ret == MPI_SUCCESS || ret == MPI_ERR_IN_STATUS)
@@ -319,58 +326,65 @@
{
int mpi_errno;
- if(reqarray[indexarray[i]] == MPI_REQUEST_NULL)
+ if(ctx->reqarray[ctx->indexarray[i]] == MPI_REQUEST_NULL)
{
int cancelled;
- MPI_Test_cancelled(&statusarray[i], &cancelled);
+ MPI_Test_cancelled(&ctx->statusarray[i], &cancelled);
if(cancelled)
{
mpi_errno = -GS_ECANCELLED;
}
else
{
- mpi_errno = statusarray[i].MPI_ERROR;
+ mpi_errno = ctx->statusarray[i].MPI_ERROR;
}
- op = gs_opcache_lookup(mpi_opcache, indexarray[i]);
+ op = gs_opcache_lookup(ctx->opcache, ctx->indexarray[i]);
+
+ /* set the status for MPI calls that pass it in (gs_mpi_recv) */
mpi_op = gs_op_entry(op, struct mpi_op, op);
if(mpi_op->status)
{
- memcpy((mpi_op->status), &(statusarray[i]), sizeof(MPI_Status));
+ memcpy((mpi_op->status), &(ctx->statusarray[i]), sizeof(MPI_Status));
}
/* call the callback */
gs_invoke_callback(op, mpi_errno);
-
- /* remove the op from the operation list */
- gs_mutex_lock(&oplist_mutex);
- gs_list_del(&op->link);
- gs_mutex_unlock(&oplist_mutex);
-
- /* give the op back to the opcache */
- gs_opcache_put(mpi_opcache, op);
+ remove_op(ctx, mpi_op->op_id);
}
}
}
else
{
+ /* Not sure what to do with unknown MPI error */
return ret;
}
return 0;
}
-static int gs_mpi_cancel(gs_op_id_t op_id)
+static int gs_mpi_cancel(gs_context_t gs_ctx, gs_op_id_t op_id)
{
uint64_t cache_id;
- int api_id, ret;
+ int resource_id, ret;
struct gs_op *op;
struct mpi_op *mpi_op;
+ struct gs_hash_head *link;
+ struct mpi_context *ctx;
- cache_id = gs_id_lookup(op_id, &api_id);
- assert(api_id == gs_mpi_id);
+ gs_mutex_lock(&ctx_mutex);
+ link = gs_hash_search(context_table, gs_ctx);
+ gs_mutex_unlock(&ctx_mutex);
+ if(!link)
+ {
+ return -EINVAL;
+ }
+ ctx = gs_hash_get_entry(link, struct mpi_context, link);
- op = gs_opcache_lookup(mpi_opcache, (int)cache_id);
+ cache_id = gs_id_lookup(op_id, &resource_id);
+ assert(resource_id == gs_mpi_resource_id);
+
+ op = gs_opcache_lookup(ctx->opcache, (int)cache_id);
mpi_op = gs_op_entry(op, struct mpi_op, op);
ret = MPI_Cancel(mpi_op->request);
@@ -381,13 +395,165 @@
return 0;
}
-struct gs_api gs_mpi_api =
+static int mpi_context_compare(void *key, struct gs_hash_head *link)
{
- "mpi",
- NULL,
- gs_mpi_poll,
- gs_mpi_cancel,
- gs_mpi_context_register
+ struct mpi_context *mpi_ctx;
+
+ mpi_ctx = gs_hash_get_entry(link, struct mpi_context, link);
+ return (((gs_context_t)key) == (mpi_ctx->gs_ctx_ptr));
+}
+
+struct gs_resource gs_mpi_resource;
+
+int gs_mpi_init(void)
+{
+ context_table = gs_hash_init(mpi_context_compare, gs_hash_64bit_hash, 1024);
+ if(context_table == NULL)
+ {
+ return -ENOMEM;
+ }
+
+ gs_mpi_resource_id = gs_resource_register(&gs_mpi_resource);
+
+ mpi_initialized = 1;
+
+ return 0;
+}
+
+int gs_mpi_finalize(void)
+{
+ mpi_initialized = 0;
+
+ gs_resource_unregister(gs_mpi_resource_id);
+
+ /* might want to verify that context table is empty */
+ gs_hash_finalize(context_table);
+
+ return 0;
+}
+
+int gs_mpi_context_register(gs_context_t context)
+{
+ int ret;
+ struct mpi_context *ctx;
+
+ ctx = malloc(sizeof(*ctx));
+ if(!ctx)
+ {
+ return -ENOMEM;
+ }
+ ctx->gs_ctx_ptr = context;
+
+ ctx->array_size = MPI_TESTCOUNT_MAXSIZE;
+ ctx->array_count = 0;
+ ctx->array_mutex = GS_MUTEX_INITIALIZER;
+
+ ret = GS_OPCACHE_INIT(struct mpi_op, op, ctx->array_size, &ctx->opcache);
+ if(ret != 0)
+ {
+ free(ctx);
+ return ret;
+ }
+
+ INIT_GS_LIST_HEAD((&ctx->oplist));
+ ctx->oplist_mutex = GS_MUTEX_INITIALIZER;
+ ctx->reqarray = malloc(sizeof(*ctx->reqarray) * ctx->array_size);
+ if(!ctx->reqarray)
+ {
+ gs_opcache_destroy(ctx->opcache);
+ free(ctx);
+ return -ENOMEM;
+ }
+ /* init request array to MPI_REQUEST_NULL values */
+ memset(ctx->reqarray, MPI_REQUEST_NULL, (sizeof(*ctx->reqarray) * ctx->array_size));
+
+ ctx->indexarray = malloc(sizeof(*ctx->indexarray) * ctx->array_size);
+ if(!ctx->indexarray)
+ {
+ free(ctx->reqarray);
+ gs_opcache_destroy(ctx->opcache);
+ free(ctx);
+ return -ENOMEM;
+ }
+
+ ctx->statusarray = malloc(sizeof(*ctx->statusarray) * ctx->array_size);
+ if(!ctx->statusarray)
+ {
+ free(ctx->indexarray);
+ free(ctx->reqarray);
+ gs_opcache_destroy(ctx->opcache);
+ free(ctx);
+ return -ENOMEM;
+ }
+
+ gs_cond_init(&ctx->wait_cond, NULL);
+ ctx->ops_in_progress = 0;
+
+ gs_mutex_lock(&ctx_mutex);
+ gs_hash_add(context_table, ctx->gs_ctx_ptr, &ctx->link);
+ gs_mutex_unlock(&ctx_mutex);
+ return 0;
+}
+
+int gs_mpi_context_unregister(gs_context_t context)
+{
+ struct gs_hash_head *link;
+ struct mpi_context *ctx;
+ struct gs_op *op, *tmp;
+ struct mpi_op *mpi_op;
+ int ret;
+
+ gs_mutex_lock(&ctx_mutex);
+ link = gs_hash_search_and_remove(context_table, context);
+ gs_mutex_unlock(&ctx_mutex);
+ if(!link)
+ {
+ return -EINVAL;
+ }
+ ctx = gs_hash_get_entry(link, struct mpi_context, link);
+
+ gs_mutex_lock(&ctx->oplist_mutex);
+ /* we need to cancel and cleanup all pending MPI operations */
+ gs_list_for_each_entry_safe(op, tmp, &ctx->oplist, link)
+ {
+ mpi_op = gs_op_entry(op, struct mpi_op, op);
+ ret = MPI_Cancel(mpi_op->request);
+ if(ret == MPI_ERR_REQUEST || ret == MPI_ERR_ARG)
+ {
+ gs_mutex_unlock(&ctx->oplist_mutex);
+ return -EINVAL;
+ }
+ }
+
+ while(!gs_list_empty(&ctx->oplist))
+ {
+ gs_mutex_unlock(&ctx->oplist_mutex);
+
+ /* wait for a 1/10 seconds for MPI ops to complete */
+ gs_mpi_poll(context, 100);
+
+ gs_mutex_lock(&ctx->oplist_mutex);
+ }
+
+ gs_mutex_unlock(&ctx->oplist_mutex);
+
+ gs_cond_destroy(&ctx->wait_cond);
+ free(ctx->statusarray);
+ free(ctx->indexarray);
+ free(ctx->reqarray);
+ gs_opcache_destroy(ctx->opcache);
+ free(ctx);
+
+ return 0;
+}
+
+struct gs_resource gs_mpi_resource =
+{
+ .resource_name = "mpi",
+ .poll_context = gs_mpi_poll,
+ .cancel = gs_mpi_cancel,
+ .register_context = gs_mpi_context_register,
+ .unregister_context = gs_mpi_context_unregister
};
/*
Modified: trunk/code/src/gsl/resources/mpi/gs-mpi.gsh
===================================================================
--- trunk/code/src/gsl/resources/mpi/gs-mpi.gsh 2009-04-29 20:39:30 UTC (rev 460)
+++ trunk/code/src/gsl/resources/mpi/gs-mpi.gsh 2009-04-29 21:26:06 UTC (rev 461)
@@ -12,20 +12,19 @@
* GS errno value is returned: -GS_ECANCELLED.
*/
-/* Matches the MPI_Isend call. The return value of this function
- * will either be from MPI_Send or MPI_Isend. */
+/* Matches the MPI_send call. */
__blocking int gs_mpi_send(void *, int, MPI_Datatype, int, int, MPI_Comm);
-/* Matches the MPI_Ibsend call */
+/* Matches the MPI_bsend call */
__blocking int gs_mpi_bsend(void *, int, MPI_Datatype, int, int, MPI_Comm);
-/* Matches the MPI_Issend call */
+/* Matches the MPI_ssend call */
__blocking int gs_mpi_ssend(void *, int, MPI_Datatype, int, int, MPI_Comm);
-/* Matches the MPI_Irsend call */
+/* Matches the MPI_rsend call */
__blocking int gs_mpi_rsend(void *, int, MPI_Datatype, int, int, MPI_Comm);
-/* Matches the MPI_Irecv call */
+/* Matches the MPI_recv call */
__blocking int gs_mpi_recv(void *, int, MPI_Datatype, int, int, MPI_Comm, MPI_Status *);
#endif
Modified: trunk/code/src/gsl/resources/mpi/test/send-recv.gs
===================================================================
--- trunk/code/src/gsl/resources/mpi/test/send-recv.gs 2009-04-29 20:39:30 UTC (rev 460)
+++ trunk/code/src/gsl/resources/mpi/test/send-recv.gs 2009-04-29 21:26:06 UTC (rev 461)
@@ -47,6 +47,7 @@
{
int numprocs, rank;
gs_op_id_t op_id;
+ gs_context_t ctx;
MPI_Init(&argc, &argv);
@@ -54,11 +55,13 @@
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
gs_mpi_init();
+
+ gs_context_create(&ctx, 1, "mpi");
- send_recv_post(numprocs, rank, done_callback, NULL, NULL, NULL, &op_id);
+ send_recv_post(numprocs, rank, done_callback, NULL, NULL, ctx, &op_id);
while(done == 0)
{
- gs_poll(NULL, 10);
+ gs_poll(ctx, 10);
}
MPI_Finalize();
return 0;
1
0
Author: wozniak
Date: 2009-04-29 15:39:30 -0500 (Wed, 29 Apr 2009)
New Revision: 460
Added:
branches/code/dense-1/src/cmpi-cp/
Log:
Shell tool to move data to/from a persistent CMPI key/value store.
1
0
r459 - in branches/code/dense-1: . src/adts src/cmpi src/common/gossip src/dense-1 src/include src/mpi_tools src/mpirpc-2 test/adts
by wozniak@mcs.anl.gov 29 Apr '09
by wozniak@mcs.anl.gov 29 Apr '09
29 Apr '09
Author: wozniak
Date: 2009-04-29 15:38:28 -0500 (Wed, 29 Apr 2009)
New Revision: 459
Modified:
branches/code/dense-1/configure.ac
branches/code/dense-1/src/adts/list.c
branches/code/dense-1/src/cmpi/driver.c
branches/code/dense-1/src/cmpi/module.mk.in
branches/code/dense-1/src/cmpi/node.c
branches/code/dense-1/src/common/gossip/gossip.h
branches/code/dense-1/src/dense-1/cmpi_dense.c
branches/code/dense-1/src/dense-1/dense.c
branches/code/dense-1/src/include/dense-1.h
branches/code/dense-1/src/include/driver.h
branches/code/dense-1/src/include/list.h
branches/code/dense-1/src/include/mpi_tools.h
branches/code/dense-1/src/mpi_tools/mpi_tools.c
branches/code/dense-1/src/mpirpc-2/mpirpc.c
branches/code/dense-1/test/adts/About.txt
Log:
Basic driver tests work.
Modified: branches/code/dense-1/configure.ac
===================================================================
--- branches/code/dense-1/configure.ac 2009-04-28 22:08:00 UTC (rev 458)
+++ branches/code/dense-1/configure.ac 2009-04-29 20:38:28 UTC (rev 459)
@@ -881,6 +881,7 @@
test/basic/module.mk
test/cmpi/module.mk
test/cmpi-io/module.mk
+ test/driver/module.mk
test/gossip/module.mk
test/mpirpc-1/module.mk
test/mpirpc-2/module.mk
Modified: branches/code/dense-1/src/adts/list.c
===================================================================
--- branches/code/dense-1/src/adts/list.c 2009-04-28 22:08:00 UTC (rev 458)
+++ branches/code/dense-1/src/adts/list.c 2009-04-29 20:38:28 UTC (rev 459)
@@ -1,6 +1,8 @@
#include "list.h"
+#include "unistd.h"
+
struct list*
list_create()
{
@@ -72,6 +74,40 @@
}
/**
+ Create new list from string of words.
+ Parse words separated by space or tab, insert each into list.
+ */
+struct list*
+list_parse(char* s)
+{
+ struct list* result = list_create();
+ char* p = s;
+ char* q;
+ while (*p)
+ {
+ // Set p to start of word, q to end of word...
+ while (*p == ' ' || *p == '\t')
+ p++;
+ if (!*p)
+ break;
+ q = p+1;
+ while (! (*q == ' ' || *q == '\t' || *q == '\0'))
+ q++;
+
+ // Insert word into list...
+ char* data = malloc(q-p+1);
+ strncpy(data, p, q-p);
+ data[q-p] = '\0';
+ list_add(result, data);
+
+ // Step forward:
+ p = q;
+ }
+
+ return result;
+}
+
+/**
This is expensive: singly linked list.
*/
void*
@@ -684,10 +720,11 @@
printf("]\n");
}
-/** format specifies the output format for the data items
+/**
+ format specifies the output format for the data items
*/
void
-list_dump(char* format, struct list* target)
+list_printf(char* format, struct list* target)
{
struct list_item* item;
Modified: branches/code/dense-1/src/cmpi/driver.c
===================================================================
--- branches/code/dense-1/src/cmpi/driver.c 2009-04-28 22:08:00 UTC (rev 458)
+++ branches/code/dense-1/src/cmpi/driver.c 2009-04-29 20:38:28 UTC (rev 459)
@@ -3,46 +3,91 @@
* Command-line client for CMPI.
*/
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
#include "driver.h"
char* filename = NULL;
-struct driver*
+bool driver_quitting = false;
+
+cmpi_driver*
driver_create(void)
{
- struct driver* d =
- (struct driver*) malloc(sizeof(struct driver));
- d->command = (char*) malloc(1024*sizeof(char));
- return d;
+ cmpi_driver* driver = malloc(sizeof(cmpi_driver));
+ driver->quitting = false;
+ return driver;
}
-struct driver*
-driver_create_file(char* filename)
+bool
+driver_setup_file(cmpi_driver* driver, char* filename)
{
- struct driver* d = driver_create();
- d->source = fopen(filename, "r");
- if (d->source == NULL)
+ driver->source = fopen(filename, "r");
+ if (driver->source == NULL)
{
printf("Could not open: %s \n", filename);
- exit(1);
+ return false;
}
- return d;
+ return true;
}
-struct driver*
-driver_create_stdin()
+bool
+driver_setup_stdin(cmpi_driver* driver)
{
- struct driver* d = driver_create();
- d->source = stdin;
- return d;
+ driver->source = stdin;
+ driver->sink = stdout;
+ return true;
}
+/**
+ @return True iff the fifos were set up and opened correctly.
+*/
+bool
+driver_setup_fifo(cmpi_driver* driver)
+{
+ char fifo_in[20] = "/tmp/cmpi.fifo.in";
+ char fifo_out[20] = "/tmp/cmpi.fifo.out";
+
+ int error = mkfifo(fifo_in, S_IRUSR|S_IWUSR);
+ if (error != 0 &&
+ errno != EEXIST)
+ {
+ printf("Could not create fifo: %s\n", fifo_in);
+ return false;
+ }
+ error = mkfifo(fifo_out, S_IRUSR|S_IWUSR);
+ if (error != 0 &&
+ errno != EEXIST)
+ {
+ printf("Could not create fifo: %s\n", fifo_in);
+ return false;
+ }
+
+ driver->source = fopen(fifo_in, "r");
+ if (driver->source == NULL)
+ {
+ printf("Could not open: %s \n", fifo_in);
+ return false;
+ }
+ driver->sink = fopen(fifo_out, "w");
+ if (driver->sink == NULL)
+ {
+ printf("Could not open: %s \n", fifo_out);
+ return false;
+ }
+ return true;
+}
+
void
-driver_put(struct list* tokens)
+driver_put(cmpi_driver* driver, struct list* tokens)
{
char* key = tokens->head->next->data;
char* value = tokens->head->next->next->data;
cmpi_put(key, value);
+ fprintf(driver->sink, "put %s ok\n", key);
}
void
@@ -65,38 +110,45 @@
}
void
-driver_sleep(struct list* tokens)
+driver_lookup(struct list* tokens)
{
char* p = tokens->head->next->data;
- int i;
- sscanf(p, "%i", &i);
- sleep(i);
+ cmpi_lookup(p);
}
void
-driver_lookup(struct list* tokens)
+driver_sleep(cmpi_driver* driver, struct list* tokens)
{
char* p = tokens->head->next->data;
- cmpi_lookup(p);
+ int i;
+ SHOW_I(i);
+ sscanf(p, "%i", &i);
+ sleep(i);
+ fprintf(driver->sink, "ok\n");
+ fflush(driver->sink);
}
void
-driver_quit(void)
+driver_quit(cmpi_driver* driver)
{
+ driver->quitting = true;
cmpi_shutdown();
- NOTE("normal exit");
+ DONE;
}
void
-driver_execute(char* command)
+driver_execute(cmpi_driver* driver)
{
- char* t = command;
-
- struct list* tokens = driver_tokens(t);
-
+ SHOW_FS(driver->command);
+
+ struct list* tokens = list_parse(driver->command);
+
+ printf("got tokens: ");
+ list_printf("%s", tokens);
+
if (tokens->size == 0)
return;
-
+
char* optoken = tokens->head->data;
if (strncmp(optoken, "#", 1) == 0)
{
@@ -104,7 +156,7 @@
}
else if (strncmp(optoken, "put", 3) == 0)
{
- driver_put(tokens);
+ driver_put(driver, tokens);
}
else if (strncmp(optoken, "get", 4) == 0)
{
@@ -120,97 +172,35 @@
}
else if (strncmp(optoken, "sleep", 5) == 0)
{
- driver_sleep(tokens);
+ printf("sleep\n");
+ driver_sleep(driver, tokens);
}
else if (strncmp(optoken, "quit", 4) == 0)
{
- driver_quit();
+ driver_quit(driver);
}
- free(tokens);
+ list_destroy(tokens);
}
void
-driver_read(struct driver* d)
+driver_process(cmpi_driver* driver)
{
- while (fgets(d->command,
- 1024,
- d->source) != NULL &&
- ! cmpi_quitting)
+ gossip_ldebug(MASK_DRIVER, "\n");
+ while (fgets(driver->command,
+ CMPI_DRIVER_MAX_COMMAND,
+ driver->source) != NULL)
{
- driver_execute(d->command);
+ char* s = strchr(driver->command, '\n');
+ *s = '\0';
+ driver_execute(driver);
+ if (driver->quitting)
+ break;
}
+ fclose(driver->source);
+ fclose(driver->sink);
}
-/**
- Creates a list of pointers into the string s.
- Replaces whitespace in s with null characters so
- string operations work.
-*/
-struct list*
-driver_tokens(char* s)
-{
- struct list* result = list_create();
- char* p;
- p = s;
- while (true)
- {
- while (*p == ' ' || *p == '\t')
- {
- *p = '\0';
- p++;
- if (*p == '\0')
- goto terminate;
- }
- if (*(p+1) != '\0')
- list_add(result, p);
- while (*p != ' ')
- {
- if (*p == '\0')
- goto terminate;
- p++;
- }
- }
- terminate:
-
- return result;
-}
-
void
-options(int argc, char* argv[])
-{
- struct option options[] =
- {
- {"file", required_argument, NULL, 'f'},
- {"snooze", required_argument, NULL, 's'},
- {"tag", required_argument, NULL, 't'},
- {0, 0, 0, 0}
- };
-
- int c = 0;
- int t = 0;
- while ((c = getopt_long(argc, argv, "f:s:t:", options, &c)) != -1)
- {
- switch (c)
- {
- case 'f':
- filename = optarg;
- // printf("Using file: %s \n", filename);
- break;
- case 's':
- sscanf(optarg, "%i", &t);
- snooze_max = t;
- // printf("Snooze max: %i \n", snooze_max);
- case 't':
- sscanf(optarg, "%i", &t);
- debug_rank = t;
- }
- c++;
- }
-}
-
-#ifdef USE_DRIVER
-
-void
dump_info(char* filename)
{
int i;
@@ -229,61 +219,4 @@
fclose(f);
}
-void
-ex1(void)
-{
- sleep(mpi_size/5+3);
- dump_info("view2.out");
-
- cmpi_shutdown();
-}
-
-void
-ex2(void)
-{
- sleep(4);
- cmpi_put("MYKEY", "MYVAL");
-
- sleep(2);
- char* result;
- cmpi_get("MYKEY", &result);
-
- NOTE_S("GOT: ", result);
-
- cmpi_shutdown();
-}
-
-int
-main(int argc, char* argv[])
-{
- options(argc, argv);
-
- MPI_Init(&argc, &argv);
-
- whoami();
- if (mpi_rank == 0)
- timestamp("START", NULL);
-
- cmpi_init_client();
- cmpi_attach();
-
- NOTE("attached.");
-
- CMPI_ID v;
-
- v = cmpi_translate(1);
- NOTE_XI("RESULT: ", v, v);
- v = cmpi_translate(590011676);
- NOTE_XI("RESULT: ", v, v);
-
- cmpi_shutdown();
-
- // struct driver* d = driver_create_stdin();
- // driver_read(d);
- // ex1();
-
- MPI_Finalize();
-}
-
-#endif
Modified: branches/code/dense-1/src/cmpi/module.mk.in
===================================================================
--- branches/code/dense-1/src/cmpi/module.mk.in 2009-04-28 22:08:00 UTC (rev 458)
+++ branches/code/dense-1/src/cmpi/module.mk.in 2009-04-29 20:38:28 UTC (rev 459)
@@ -3,6 +3,7 @@
CMPI_SRC += $(DIR)/cmpi.c
CMPI_SRC += $(DIR)/node.c
+CMPI_SRC += $(DIR)/driver.c
ifeq (@USE_TABLE_DENSE@,1)
CMPI_SRC += $(DIR)/dense.c
Modified: branches/code/dense-1/src/cmpi/node.c
===================================================================
--- branches/code/dense-1/src/cmpi/node.c 2009-04-28 22:08:00 UTC (rev 458)
+++ branches/code/dense-1/src/cmpi/node.c 2009-04-29 20:38:28 UTC (rev 459)
@@ -19,8 +19,10 @@
void
dmalloc_setup(void)
{
+ gossip_ldebug(MASK_DEBUG, "\n");
sprintf(dmalloc_logpath, "./dmalloc_%i.out", debug_rank);
printf("DMALLOC_PATH: %s \n", dmalloc_logpath);
+ gossip_ldebug(MASK_DEBUG, "dmalloc_setup done");
}
#endif
@@ -154,12 +156,15 @@
int
main(int argc, char* argv[])
{
+ gossip_set_debug_mask(1, MASK_DEBUG|MASK_MPIRPC|MASK_DRIVER);
+
// Comment out to achieve deterministic results:
srand((unsigned int) time(NULL));
// Basic MPI startup...
MPI_Init(&argc, &argv);
whoami();
+
if (mpi_rank == 0)
{
DEBUG(timestamp("START", NULL));
Modified: branches/code/dense-1/src/common/gossip/gossip.h
===================================================================
--- branches/code/dense-1/src/common/gossip/gossip.h 2009-04-28 22:08:00 UTC (rev 458)
+++ branches/code/dense-1/src/common/gossip/gossip.h 2009-04-29 20:38:28 UTC (rev 459)
@@ -29,9 +29,11 @@
// Masks:
#define MASK_NONE ((uint64_t)0)
-#define MASK_MPIRPC ((uint64_t)1 << 0)
-#define MASK_KDA ((uint64_t)1 << 1)
-#define MASK_ADT ((uint64_t)1 << 2)
+#define MASK_DEBUG ((uint64_t)1 << 1)
+#define MASK_MPIRPC ((uint64_t)1 << 2)
+#define MASK_DHT ((uint64_t)1 << 3)
+#define MASK_ADT ((uint64_t)1 << 4)
+#define MASK_DRIVER ((uint64_t)1 << 5)
/********************************************************************
* Visible interface
Modified: branches/code/dense-1/src/dense-1/cmpi_dense.c
===================================================================
--- branches/code/dense-1/src/dense-1/cmpi_dense.c 2009-04-28 22:08:00 UTC (rev 458)
+++ branches/code/dense-1/src/dense-1/cmpi_dense.c 2009-04-29 20:38:28 UTC (rev 459)
@@ -29,7 +29,7 @@
for (i = 0; i < dense_nodes; i++)
{
- // NOTE_I("contact: ", i);
+ gossip_debug(MASK_DHT, "contact: %i\n", i);
inlist_add(contacts, i);
}
@@ -178,6 +178,7 @@
MPIRPC_Node_make(MPI_COMM_WORLD, item->data, &node);
DENSE_Shutdown(node);
}
+ DONE;
}
void
Modified: branches/code/dense-1/src/dense-1/dense.c
===================================================================
--- branches/code/dense-1/src/dense-1/dense.c 2009-04-28 22:08:00 UTC (rev 458)
+++ branches/code/dense-1/src/dense-1/dense.c 2009-04-29 20:38:28 UTC (rev 459)
@@ -64,7 +64,6 @@
void
rpc_bootping()
{
- NOTE_F;
if (mpi_rank < dense_nodes-1)
{
MPIRPC_Node node;
Modified: branches/code/dense-1/src/include/dense-1.h
===================================================================
--- branches/code/dense-1/src/include/dense-1.h 2009-04-28 22:08:00 UTC (rev 458)
+++ branches/code/dense-1/src/include/dense-1.h 2009-04-29 20:38:28 UTC (rev 459)
@@ -5,8 +5,10 @@
#include <cmpi.h>
#include <inlist.h>
#include <string.h>
+#include <strings.h>
+
#ifdef USE_STRINGS_H
-#include <strings.h>
+
#endif
typedef int DENSE_ID;
Modified: branches/code/dense-1/src/include/driver.h
===================================================================
--- branches/code/dense-1/src/include/driver.h 2009-04-28 22:08:00 UTC (rev 458)
+++ branches/code/dense-1/src/include/driver.h 2009-04-29 20:38:28 UTC (rev 459)
@@ -7,20 +7,40 @@
#include <cmpi.h>
-struct driver
+/**
+ Maximum command line for driver.
+*/
+#define CMPI_DRIVER_MAX_COMMAND (100+CMPI_KEY_LENGTH)
+
+typedef struct cmpi_driver_
{
FILE* source;
- char* command;
+ FILE* sink;
+ char command[CMPI_DRIVER_MAX_COMMAND];
+ char data[CMPI_VALUE_LENGTH];
+ bool quitting;
+} cmpi_driver;
+
+enum
+{
+ CMPI_DRIVER_FILE,
+ CMPI_DRIVER_STDIN,
+ CMPI_DRIVER_PIPE
};
-struct driver* driver_create_file(char* filename);
-struct driver* driver_create_stdin(void);
+//// API...
-/**
- Creates a list of pointers into the string s.
- Replaces spaces in s with null characters so
- string operations work.
-*/
-struct list* driver_tokens(char* s);
+cmpi_driver* driver_create(void);
-void driver_read(struct driver* d);
+bool driver_setup_stdin(cmpi_driver* driver);
+bool driver_setup_file(cmpi_driver* driver, char* filename);
+bool driver_setup_fifo(cmpi_driver* driver);
+
+void driver_process(cmpi_driver* driver);
+
+//// Internal functions...
+
+struct list* driver_tokens(cmpi_driver* driver);
+
+
+
Modified: branches/code/dense-1/src/include/list.h
===================================================================
--- branches/code/dense-1/src/include/list.h 2009-04-28 22:08:00 UTC (rev 458)
+++ branches/code/dense-1/src/include/list.h 2009-04-29 20:38:28 UTC (rev 459)
@@ -37,6 +37,8 @@
struct list_item* list_add(struct list* target, void* data);
#define list_push(target, data) list_add(target, data)
+struct list* list_parse(char* s);
+
/**
Add this data if list_inspect does not find it.
*/
@@ -131,7 +133,7 @@
void list_output(char* (*f)(void*), struct list* target);
-void list_dump(char* format, struct list* target);
+void list_printf(char* format, struct list* target);
int list_tostring(char* str, size_t size,
char* format, struct list* target);
Modified: branches/code/dense-1/src/include/mpi_tools.h
===================================================================
--- branches/code/dense-1/src/include/mpi_tools.h 2009-04-28 22:08:00 UTC (rev 458)
+++ branches/code/dense-1/src/include/mpi_tools.h 2009-04-29 20:38:28 UTC (rev 459)
@@ -19,6 +19,8 @@
#endif
#endif
+#include <gossip.h>
+
extern int mpi_rank;
extern int mpi_size;
@@ -26,17 +28,19 @@
extern FILE* debug_file;
-/** Quick setup
+/**
+ Quick setup
*/
void whoami(void);
-/** Output msgs in rank order.
+/**
+ Output msgs in rank order.
*/
void sync_output(int rank, int size, char* msg);
-char* heap(char* s);
-char* iheap(int i);
-char* xheap(int i);
+char* heap(char* s);
+char* iheap(int i);
+char* xheap(int i);
/** Execute code line or block in rank order.
*/
Modified: branches/code/dense-1/src/mpi_tools/mpi_tools.c
===================================================================
--- branches/code/dense-1/src/mpi_tools/mpi_tools.c 2009-04-28 22:08:00 UTC (rev 458)
+++ branches/code/dense-1/src/mpi_tools/mpi_tools.c 2009-04-29 20:38:28 UTC (rev 459)
@@ -38,6 +38,8 @@
void whoami()
{
+ gossip_ldebug(MASK_DEBUG, "\n");
+
MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
Modified: branches/code/dense-1/src/mpirpc-2/mpirpc.c
===================================================================
--- branches/code/dense-1/src/mpirpc-2/mpirpc.c 2009-04-28 22:08:00 UTC (rev 458)
+++ branches/code/dense-1/src/mpirpc-2/mpirpc.c 2009-04-29 20:38:28 UTC (rev 459)
@@ -281,7 +281,7 @@
NOTE_FS(name);
MPIRPC* rpc = MPIRPC_Call(target, name, args, NULL, NULL);
MPIRPC_Wait(rpc);
- NOTE_S("Unblocked: ", name);
+ gossip_do(MASK_MPIRPC, NOTE_S("Unblocked: ", name));
result = rpc->result;
MPIRPC_Free(rpc);
return result;
@@ -290,7 +290,6 @@
void
MPIRPC_Request(MPIRPC_Node caller)
{
- NOTE_F;
MPI_Status status;
char name[MPIRPC_MAX_NAME];
@@ -324,8 +323,6 @@
else
args = NULL;
- NOTE("Request recvd.");
-
/* printf("\t [%i] %s(%s) for %i \n",
mpi_rank, name, args, caller); */
@@ -371,7 +368,6 @@
MPIRPC_Retrieve(MPIRPC_Node sender)
{
int i;
- NOTE_F;
MPI_Status status;
int unique;
@@ -439,7 +435,7 @@
if (channel->request == MPI_REQUEST_NULL)
{
- NOTE("Posting Irecv...");
+ // gossip_debug(MASK_MPIRPC, "Posting Irecv...\n");
MPI_Irecv(&check_msg, 1, MPI_INT, MPI_ANY_SOURCE,
MPIRPC_TAG_CONTROL, channel->comm,
&channel->request);
@@ -561,17 +557,12 @@
MPI_Send(&mpirpc_msg_disconnect, 1, MPI_INT,
0, MPIRPC_TAG_CONTROL, channel->comm);
- NOTE("SENT");
MPI_Status status;
MPI_Recv(&response, 1, MPI_INT,
0, MPIRPC_TAG_CONTROL, channel->comm, &status);
- NOTE("RECVD");
-
MPIRPC_Comm_remove(&channel->comm);
- NOTE("OK");
-
assert(response == MPIRPC_MSG_OK);
}
@@ -668,7 +659,7 @@
void
MPIRPC_Free(MPIRPC* rpc)
{
- SHOW_FSI(rpc->name, rpc->unique);
+ gossip_do(MASK_MPIRPC, SHOW_FSI(rpc->name, rpc->unique));
free(rpc->args);
free(rpc);
}
Modified: branches/code/dense-1/test/adts/About.txt
===================================================================
--- branches/code/dense-1/test/adts/About.txt 2009-04-28 22:08:00 UTC (rev 458)
+++ branches/code/dense-1/test/adts/About.txt 2009-04-29 20:38:28 UTC (rev 459)
@@ -3,4 +3,6 @@
test02: Tests lru_table
test03: Tests ilist
test04: Tests inlist
+test05: Tests lru_table
+test06: Tests list
1
0
r458 - in trunk/code/src/gsl: . common include resources resources/mpi resources/mpi/test resources/timer tests/correctness
by slang@mcs.anl.gov 28 Apr '09
by slang@mcs.anl.gov 28 Apr '09
28 Apr '09
Author: slang
Date: 2009-04-28 17:08:00 -0500 (Tue, 28 Apr 2009)
New Revision: 458
Added:
trunk/code/src/gsl/common/
trunk/code/src/gsl/common/Makefile
trunk/code/src/gsl/common/gs-opcache.c
trunk/code/src/gsl/common/gs.c
trunk/code/src/gsl/include/gs-op.h
trunk/code/src/gsl/include/gs-opcache.h
trunk/code/src/gsl/resources/
trunk/code/src/gsl/resources/mpi/
trunk/code/src/gsl/resources/mpi/Makefile
trunk/code/src/gsl/resources/mpi/gs-mpi.c
trunk/code/src/gsl/resources/mpi/gs-mpi.gsh
trunk/code/src/gsl/resources/mpi/gs-mpi.h
trunk/code/src/gsl/resources/mpi/test/
trunk/code/src/gsl/resources/mpi/test/Makefile
trunk/code/src/gsl/resources/mpi/test/send-recv.gs
trunk/code/src/gsl/resources/timer/
trunk/code/src/gsl/resources/timer/Makefile
trunk/code/src/gsl/resources/timer/gs-timer.c
trunk/code/src/gsl/resources/timer/gs-timer.gsh
trunk/code/src/gsl/resources/timer/gs-timer.h
Removed:
trunk/code/src/gsl/gs.c
Modified:
trunk/code/src/gsl/Makefile
trunk/code/src/gsl/gs-parser
trunk/code/src/gsl/gs-parser.lhs
trunk/code/src/gsl/gscc
trunk/code/src/gsl/include/gs-hash.h
trunk/code/src/gsl/include/gs-list.h
trunk/code/src/gsl/include/gs.h
trunk/code/src/gsl/tests/correctness/Makefile
trunk/code/src/gsl/tests/correctness/forloop.gs
trunk/code/src/gsl/tests/correctness/parallel1.gs
trunk/code/src/gsl/tests/correctness/parallelfor.gs
Log:
add some resources, other changes/fixes.
Modified: trunk/code/src/gsl/Makefile
===================================================================
--- trunk/code/src/gsl/Makefile 2009-04-28 16:16:51 UTC (rev 457)
+++ trunk/code/src/gsl/Makefile 2009-04-28 22:08:00 UTC (rev 458)
@@ -5,18 +5,10 @@
allfiles=$(lhsfiles) $(hsfiles)
-all: gs-parser gslib
+all: gs-parser
gs-parser: $(allfiles)
ghc --make gs-parser.lhs
-gslib: libgs.a
-
-libgs.a: gs.o
- ar rcs $@ gs.o
-
-gs.o: gs.c include/gs.h
- $(CC) -g -I./include -o $@ -c $<
-
clean::
rm -rf *.o *.hi gs-parser
Added: trunk/code/src/gsl/common/Makefile
===================================================================
--- trunk/code/src/gsl/common/Makefile (rev 0)
+++ trunk/code/src/gsl/common/Makefile 2009-04-28 22:08:00 UTC (rev 458)
@@ -0,0 +1,13 @@
+
+all: gslib
+
+gslib: libgs.a
+
+libgs.a: gs.o gs-opcache.o
+ ar rcs $@ gs.o gs-opcache.o
+
+gs.o: gs.c ../include/gs.h
+ $(CC) -g -I../include -o $@ -c $<
+
+gs-opcache.o: gs-opcache.c ../include/gs-opcache.h
+ $(CC) -g -I../include -o $@ -c $<
Added: trunk/code/src/gsl/common/gs-opcache.c
===================================================================
--- trunk/code/src/gsl/common/gs-opcache.c (rev 0)
+++ trunk/code/src/gsl/common/gs-opcache.c 2009-04-28 22:08:00 UTC (rev 458)
@@ -0,0 +1,126 @@
+
+#include <errno.h>
+#include "gs-list.h"
+#include "gs-opcache.h"
+
+struct gs_opcache
+{
+ void *array;
+ int size;
+ int count;
+ gs_mutex_t mutex;
+ struct gs_list_head free_list;
+ int typesize;
+ int member_offset;
+};
+
+int gs_opcache_init(int typesize, int member_offset, int init_size, gs_opcache_t *cache)
+{
+ struct gs_opcache *c;
+ c = malloc(sizeof(*c));
+ if(!c)
+ {
+ return -ENOMEM;
+ }
+ c->size = init_size;
+ c->array = malloc(typesize * init_size);
+ if(!c->array)
+ {
+ free(c);
+ return -ENOMEM;
+ }
+ c->typesize = typesize;
+ c->member_offset = member_offset;
+ c->count = 0;
+ c->mutex = GS_MUTEX_INITIALIZER;
+ INIT_GS_LIST_HEAD(&(c->free_list));
+ *cache = c;
+ return 0;
+}
+
+int gs_opcache_double_size(gs_opcache_t cache)
+{
+ gs_mutex_lock(&cache->mutex);
+ cache->size *= 2;
+ cache->array = realloc(cache->array, cache->typesize * cache->size);
+ if(!cache->array)
+ {
+ free(cache);
+ gs_mutex_unlock(&cache->mutex);
+ return -ENOMEM;
+ }
+ gs_mutex_unlock(&cache->mutex);
+ return 0;
+}
+
+int gs_opcache_destroy(gs_opcache_t cache)
+{
+ gs_mutex_lock(&cache->mutex);
+ free(cache->array);
+ free(cache);
+ gs_mutex_unlock(&cache->mutex);
+ return 0;
+}
+
+inline int gs_opcache_size(gs_opcache_t cache)
+{
+ return cache->size;
+}
+
+inline int gs_opcache_count(gs_opcache_t cache)
+{
+ return cache->count;
+}
+
+struct gs_op *gs_opcache_get(gs_opcache_t cache)
+{
+ struct gs_list_head *entry;
+ struct gs_op *op;
+
+ gs_mutex_lock(&cache->mutex);
+ if(gs_list_empty(&cache->free_list))
+ {
+ if(cache->count == cache->size)
+ {
+ gs_opcache_double_size(cache);
+ }
+
+ op = (struct gs_op *)(((char *)cache->array) +
+ (cache->count * cache->typesize) +
+ cache->member_offset);
+ op->cache_id = cache->count;
+ ++cache->count;
+ }
+ else
+ {
+ entry = gs_list_pop(&cache->free_list);
+ op = gs_list_get_entry(entry, struct gs_op, link);
+ }
+ gs_mutex_unlock(&cache->mutex);
+ return op;
+}
+
+int gs_opcache_put(gs_opcache_t cache, struct gs_op *op)
+{
+ gs_mutex_lock(&cache->mutex);
+ gs_list_push(&cache->free_list, &(op->link));
+ gs_mutex_unlock(&cache->mutex);
+
+ return 0;
+}
+
+struct gs_op *gs_opcache_lookup(gs_opcache_t cache, int id)
+{
+ return (struct gs_op *)(((char *)cache->array) +
+ (id * cache->typesize) +
+ cache->member_offset);
+}
+
+/*
+ * Local variables:
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * End:
+ *
+ * vim: ts=8 sts=4 sw=4 expandtab
+ */
Added: trunk/code/src/gsl/common/gs.c
===================================================================
--- trunk/code/src/gsl/common/gs.c (rev 0)
+++ trunk/code/src/gsl/common/gs.c 2009-04-28 22:08:00 UTC (rev 458)
@@ -0,0 +1,176 @@
+
+#include "gs.h"
+#include <errno.h>
+
+struct gs_resource_entry
+{
+ int id;
+ struct gs_resource resource;
+};
+
+static int gs_resource_count = 0;
+static struct gs_resource_entry gs_resource_entries[GS_MAX_RESOURCES];
+
+int gs_register_resource(struct gs_resource *resource)
+{
+ int index = gs_resource_count;
+
+ if(gs_resource_count == GS_MAX_APIS)
+ {
+ return -EINVAL;
+ }
+
+
+ gs_api_entries[index].id = gs_api_count;
+ gs_api_entries[index].api.api_name = api->api_name;
+ gs_api_entries[index].api.test = api->test;
+ gs_api_entries[index].api.poll_context = api->poll_context;
+ gs_api_entries[index].api.cancel = api->cancel;
+ gs_api_count++;
+ return index;
+}
+
+int gs_cancel_op(gs_op_id_t op_id)
+{
+ struct gs_ctl *ctl;
+ int api_id;
+ int ret = -EINVAL;
+
+ gs_id_lookup(op_id, &api_id);
+ if(api_id > gs_api_count)
+ {
+ gs_mutex_unlock(&ctl->mutex);
+ return -EINVAL;
+ }
+
+ if(api_id == 0)
+ {
+ ctl = (struct gs_ctl *)(intptr_t)gs_id_lookup(op_id, NULL);
+ gs_mutex_lock(&ctl->mutex);
+ if(ctl->cancelled)
+ {
+ /* already cancelled! */
+ gs_mutex_unlock(&ctl->mutex);
+ return -EINVAL;
+ }
+
+ ctl->cancelled = 1;
+ if(ctl->in_pwait)
+ {
+ /* cancel children */
+ struct gs_list_head *entry;
+ struct gs_ctl *child_ctl;
+ if(gs_list_empty(&ctl->children))
+ {
+ return -EINVAL;
+ }
+
+ gs_list_for_each(entry, &ctl->children)
+ {
+ child_ctl = gs_list_get_entry(entry, typeof(*child_ctl), link);
+ ret = gs_cancel_op(child_ctl->current_op_id);
+ if(ret != 0)
+ {
+ /* cancel failed */
+ gs_mutex_unlock(&ctl->mutex);
+ }
+ }
+ }
+ else
+ {
+ ret = gs_cancel_op(ctl->current_op_id);
+ }
+ gs_mutex_unlock(&ctl->mutex);
+ return ret;
+ }
+
+ ret = gs_api_entries[api_id].api.cancel(op_id);
+ gs_mutex_unlock(&ctl->mutex);
+ return ret;
+}
+
+gs_op_id_t gs_id_gen(int api_id, uint64_t ptr)
+{
+ return (gs_op_id_t)(GS_GET_API_MASK(api_id) | ptr);
+}
+
+uint64_t gs_id_lookup(gs_op_id_t id, int *api_id)
+{
+ if(api_id) *api_id = GS_GET_API_ID(id);
+ return (~GS_API_MASK)&id;
+}
+
+int gs_cancel_children(void *ptr)
+{
+ int ret;
+ struct gs_ctl *ctl;
+ struct gs_ctl *child_ctl;
+ struct gs_list_head *entry;
+
+ ctl = (struct gs_ctl *)ptr;
+ if(gs_list_empty(&ctl->children))
+ {
+ return -EINVAL;
+ }
+
+ gs_list_for_each(entry, &ctl->children)
+ {
+ child_ctl = gs_list_get_entry(entry, typeof(*child_ctl), link);
+ ret = gs_cancel_op(child_ctl->current_op_id);
+ if(ret != 0)
+ {
+ /* cancel failed */
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+#include <execinfo.h>
+#include <stdio.h>
+
+void gs_backtrace(void)
+{
+ void *trace[16];
+ char **messages = (char **)NULL;
+ int size, i;
+
+ size = backtrace(trace, 16);
+ messages = backtrace_symbols(trace, size);
+ for(i = 0; i < size; ++i)
+ {
+ fprintf(stderr, "gsl backtrace: %s\n", messages[i]);
+ }
+}
+
+#include <assert.h>
+
+void gs_assert(const char *str, int expr)
+{
+ if(!expr)
+ {
+ fprintf(stderr, "%s\n", str);
+ gs_backtrace();
+ assert(expr);
+ }
+}
+
+int gs_poll(gs_context_t context, int millisecs)
+{
+ int resource_ms, i, ret;
+
+ resource_ms = millisecs / gs_api_count;
+
+ for(i = 0; i < gs_resource_count; ++i)
+ {
+ ret = gs_resource_entries[i].api.poll_context(context, resource_ms);
+ if(ret != 0)
+ {
+ return ret;
+ }
+ }
+ return 0;
+}
+
+int gs_context_create(gs_context_t *context,
Modified: trunk/code/src/gsl/gs-parser
===================================================================
(Binary files differ)
Modified: trunk/code/src/gsl/gs-parser.lhs
===================================================================
--- trunk/code/src/gsl/gs-parser.lhs 2009-04-28 16:16:51 UTC (rev 457)
+++ trunk/code/src/gsl/gs-parser.lhs 2009-04-28 22:08:00 UTC (rev 458)
@@ -3,6 +3,8 @@
> import Language.C.System.GCC -- preprocessor used
> import Language.C.Data.Ident
> import System.Environment
+> import System.Console.GetOpt
+> import System.Exit
> import Data.Typeable
> import Data.Maybe
> import Data.Either
@@ -74,7 +76,7 @@
> \ "++prefix++"->completed = 0; \
> \ "++prefix++"->allposted = 0; \
> \ "++prefix++"->hit_pbreak = 0; \
-> \ "++prefix++"->mutex = GS_MUTEX_INITIALIZER; \
+> \ "++prefix++"->mutex = 0; \
> \ "++prefix++"->parent = (void *)0; \
> \ "++prefix++"->children.next = &("++prefix++"->children); \
> \ "++prefix++"->children.prev = &("++prefix++"->children); \
@@ -585,6 +587,10 @@
> postStmts <- generatePostStmts (Just first) []
> return $ tlInitStmts ++ postStmts
+> generateFirstPostStmts b@(FunContext f _ _ _ _) =
+> let fname = getFunDefName f
+> in error $
+> "The blocking function: " ++ fname ++ " does not contain any blocking statements\n"
> generateFirstPostStmts _ = error "Not a FunContext. Invalid code path."
generatePostStmts makes the post call statements for a callback (or post function).
@@ -1210,17 +1216,42 @@
> Left parse_err -> error (show parse_err)
> Right ast -> return ast
-> parseFile :: FilePath -> IO ()
-> parseFile f = do
+> parseFile :: Bool -> FilePath -> IO ()
+> parseFile p f = do
> w <- newWalkerState f mkErrorPostHandler transformFuncReturnStmts
> ctu <- generateAST f
> (ctuWithPostDecls, w) <- runStateT (registerBlockingFunDecls ctu) w
> (transCTU, w) <- runStateT (transformBlockingDefs ctuWithPostDecls) w
-> (print . pretty) transCTU
-> -- (print . serialize) transCTU
+> if p then (print . pretty) transCTU
+> else (print . serialize) transCTU
> return ()
+> data ParserOpts = Pretty | Help
+
+> parserOpts :: [OptDescr ParserOpts]
+> parserOpts =
+> [ Option ['p'] ["pretty"] (NoArg Pretty)
+> "output in pretty form without source line macros"
+> , Option ['h','?'] ["help"] (NoArg Help)
+> "help text"
+> ]
+
+> optPretty :: ParserOpts -> Bool
+> optPretty (Pretty) = True
+> optPretty _ = False
+
+> optHelp :: ParserOpts -> Bool
+> optHelp (Help) = True
+> optHelp _ = False
+
> main :: IO ()
> main = do
-> files <- getArgs
-> mapM_ parseFile files
+> args <- getArgs
+> let (opts, files, errs) = getOpt RequireOrder parserOpts args
+> pretty = any optPretty opts
+> help = any optHelp opts
+> header = "Usage: gs-parser [OPTIONS...] files..."
+> when (not $ null errs) $ ioError $ userError (concat errs ++
+> usageInfo header parserOpts)
+> when help $ do { putStrLn $ usageInfo header parserOpts ; exitWith (ExitFailure 1) }
+> mapM_ (parseFile pretty) files
Deleted: trunk/code/src/gsl/gs.c
===================================================================
--- trunk/code/src/gsl/gs.c 2009-04-28 16:16:51 UTC (rev 457)
+++ trunk/code/src/gsl/gs.c 2009-04-28 22:08:00 UTC (rev 458)
@@ -1,155 +0,0 @@
-
-#include "gs.h"
-#include <errno.h>
-
-struct gs_api_entry
-{
- int id;
- struct gs_api api;
-};
-
-static int gs_api_count = 0;
-static struct gs_api_entry gs_api_entries[GS_MAX_APIS];
-
-int gs_register_api(struct gs_api *api)
-{
- if(gs_api_count == GS_MAX_APIS)
- {
- return -EINVAL;
- }
-
- gs_api_count++;
-
- gs_api_entries[gs_api_count].id = gs_api_count;
- gs_api_entries[gs_api_count].api.api_name = api->api_name;
- gs_api_entries[gs_api_count].api.test = api->test;
- gs_api_entries[gs_api_count].api.poll_context = api->poll_context;
- gs_api_entries[gs_api_count].api.cancel = api->cancel;
- return gs_api_count;
-}
-
-int gs_cancel_op(gs_op_id_t op_id)
-{
- struct gs_ctl *ctl;
- int api_id;
- int ret = -EINVAL;
-
- gs_id_lookup(op_id, &api_id);
- if(api_id > gs_api_count)
- {
- gs_mutex_unlock(&ctl->mutex);
- return -EINVAL;
- }
-
- if(api_id == 0)
- {
- ctl = (struct gs_ctl *)(intptr_t)gs_id_lookup(op_id, NULL);
- gs_mutex_lock(&ctl->mutex);
- if(ctl->cancelled)
- {
- /* already cancelled! */
- gs_mutex_unlock(&ctl->mutex);
- return -EINVAL;
- }
-
- ctl->cancelled = 1;
- if(ctl->in_pwait)
- {
- /* cancel children */
- struct gs_list_head *entry;
- struct gs_ctl *child_ctl;
- if(gs_list_empty(&ctl->children))
- {
- return -EINVAL;
- }
-
- gs_list_for_each(entry, &ctl->children)
- {
- child_ctl = gs_list_get_entry(entry, typeof(*child_ctl), link);
- ret = gs_cancel_op(child_ctl->current_op_id);
- if(ret != 0)
- {
- /* cancel failed */
- gs_mutex_unlock(&ctl->mutex);
- }
- }
- }
- else
- {
- ret = gs_cancel_op(ctl->current_op_id);
- }
- gs_mutex_unlock(&ctl->mutex);
- return ret;
- }
-
- ret = gs_api_entries[api_id].api.cancel(op_id);
- gs_mutex_unlock(&ctl->mutex);
- return ret;
-}
-
-gs_op_id_t gs_id_gen(int api_id, uint64_t ptr)
-{
- return (gs_op_id_t)(GS_GET_API_MASK(api_id) | ptr);
-}
-
-uint64_t gs_id_lookup(gs_op_id_t id, int *api_id)
-{
- if(api_id) *api_id = GS_GET_API_ID(id);
- return (~GS_API_MASK)&id;
-}
-
-int gs_cancel_children(void *ptr)
-{
- int ret;
- struct gs_ctl *ctl;
- struct gs_ctl *child_ctl;
- struct gs_list_head *entry;
-
- ctl = (struct gs_ctl *)ptr;
- if(gs_list_empty(&ctl->children))
- {
- return -EINVAL;
- }
-
- gs_list_for_each(entry, &ctl->children)
- {
- child_ctl = gs_list_get_entry(entry, typeof(*child_ctl), link);
- ret = gs_cancel_op(child_ctl->current_op_id);
- if(ret != 0)
- {
- /* cancel failed */
- return ret;
- }
- }
-
- return 0;
-}
-
-#include <execinfo.h>
-#include <stdio.h>
-
-void gs_backtrace(void)
-{
- void *trace[16];
- char **messages = (char **)NULL;
- int size, i;
-
- size = backtrace(trace, 16);
- messages = backtrace_symbols(trace, size);
- for(i = 0; i < size; ++i)
- {
- fprintf(stderr, "gsl backtrace: %s\n", messages[i]);
- }
-}
-
-#include <assert.h>
-
-void gs_assert(const char *str, int expr)
-{
- if(!expr)
- {
- fprintf(stderr, "%s\n", str);
- gs_backtrace();
- assert(expr);
- }
-}
Modified: trunk/code/src/gsl/gscc
===================================================================
--- trunk/code/src/gsl/gscc 2009-04-28 16:16:51 UTC (rev 457)
+++ trunk/code/src/gsl/gscc 2009-04-28 22:08:00 UTC (rev 458)
@@ -23,7 +23,7 @@
exit $res
fi
-gcc -g -x c -c -o $gsfile.o $gsfile.i
+${CC} -g -x c -c -o $gsfile.o $gsfile.i
res=$?
if test $res != 0; then
echo "compiling parsed $gsfile Failed!" 1>&2
Modified: trunk/code/src/gsl/include/gs-hash.h
===================================================================
--- trunk/code/src/gsl/include/gs-hash.h 2009-04-28 16:16:51 UTC (rev 457)
+++ trunk/code/src/gsl/include/gs-hash.h 2009-04-28 22:08:00 UTC (rev 458)
@@ -9,6 +9,7 @@
#include <stdlib.h>
#include <stdint.h>
#include "gs-list.h"
+#include "gs.h"
#define gs_hash_head gs_list_head
@@ -18,6 +19,7 @@
int table_size;
int (*compare) (void *key, struct gs_hash_head * link);
int (*hash) (void *key, int table_size);
+ gs_mutex_t lock;
#ifdef __KERNEL__
spinlock_t lock;
@@ -32,7 +34,7 @@
*
* returns pointer to table on success, NULL on failure
*/
-static inline struct gs_hash_table *qhash_init(
+static inline struct gs_hash_table *gs_hash_init(
int (*compare) (void *key,
struct gs_hash_head * link),
int (*hash) (void *key,
@@ -43,7 +45,7 @@
struct gs_hash_table *new_table = NULL;
/* create struct to contain table information */
- new_table = (struct gs_hash_table *)malloc(sizeof(struct qhash_table));
+ new_table = (struct gs_hash_table *)malloc(sizeof(struct gs_hash_table));
if (!new_table)
{
return (NULL);
@@ -56,7 +58,7 @@
/* create array for actual table */
new_table->array = (struct gs_hash_head *)
- gs_hash_malloc(sizeof(struct qhash_head) * table_size);
+ malloc(sizeof(struct gs_hash_head) * table_size);
if (!new_table->array)
{
free(new_table);
@@ -66,9 +68,8 @@
/* initialize a doubly linked at each hash table index */
for (i = 0; i < table_size; i++)
{
- INIT_QLIST_HEAD(&new_table->array[i]);
+ INIT_GS_LIST_HEAD(&new_table->array[i]);
}
- gs_mutex_init(&new_table->lock);
return (new_table);
}
@@ -83,8 +84,8 @@
static inline void gs_hash_finalize(
struct gs_hash_table *old_table)
{
- gs_hash_free(old_table->array);
- gs_hash_free(old_table);
+ free(old_table->array);
+ free(old_table);
return;
}
@@ -120,7 +121,7 @@
* returns pointer to link on success, NULL on failure (or item
* not found)
*/
-static inline struct gs_hash_head *qhash_search(
+static inline struct gs_hash_head *gs_hash_search(
struct gs_hash_table *table,
void *key)
{
@@ -181,7 +182,7 @@
* returns pointer to link on success, NULL on failure (or item
* not found). On success, link is removed from hashtable.
*/
-static inline struct gs_hash_head *qhash_search_and_remove(
+static inline struct gs_hash_head *gs_hash_search_and_remove(
struct gs_hash_table *table,
void *key)
{
@@ -214,7 +215,7 @@
* returns pointer to link on success, NULL on failure (or item
* not found). On success, link is removed from hashtable.
*/
-static inline struct gs_hash_head *qhash_search_and_remove_at_index(
+static inline struct gs_hash_head *gs_hash_search_and_remove_at_index(
struct gs_hash_table *table,
int index)
{
Modified: trunk/code/src/gsl/include/gs-list.h
===================================================================
--- trunk/code/src/gsl/include/gs-list.h 2009-04-28 16:16:51 UTC (rev 457)
+++ trunk/code/src/gsl/include/gs-list.h 2009-04-28 22:08:00 UTC (rev 458)
@@ -222,6 +222,8 @@
return NULL;
}
+#define gs_list_push(__list, __entry) gs_list_add_tail((__entry), (__list))
+
static inline struct gs_list_head * gs_list_pop(struct gs_list_head *list)
{
struct gs_list_head *entry = list->next;
@@ -230,12 +232,10 @@
return entry;
}
-static inline struct gs_list_head * gs_list_pop_tail(struct gs_list_head *list)
+static inline struct gs_list_head *gs_list_peek(struct gs_list_head *list)
{
- struct gs_list_head *entry = list->prev;
- if(gs_list_empty(list)) return NULL;
- gs_list_del(list->prev);
- return entry;
+ if(list->next == list) return NULL;
+ return list->next;
}
#endif
Added: trunk/code/src/gsl/include/gs-op.h
===================================================================
--- trunk/code/src/gsl/include/gs-op.h (rev 0)
+++ trunk/code/src/gsl/include/gs-op.h 2009-04-28 22:08:00 UTC (rev 458)
@@ -0,0 +1,40 @@
+
+#ifndef __GS_OPCACHE_H__
+#define __GS_OPCACHE_H__
+
+#include "gs.h"
+
+struct gs_op
+{
+ int index;
+ void (*callback)(void *ptr, int ret);
+ void *user_ptr;
+ gs_hints_t hints;
+ gs_context_t ctx;
+ int cache_id;
+ struct gs_list_head link;
+};
+
+#define gs_op_entry(_op, _type, _member) \
+ ((_type *)((char *)(_op) - (unsigned long)((&((_type *)0)->_member))))
+
+#define gs_invoke_callback(_op, _result) (_op)->callback((_op)->user_ptr, _result)
+
+#define gs_op_fill(_op, _cb, _up, _hints, _ctx) \
+ do { \
+ (_op)->callback = (_cb); \
+ (_op)->user_ptr = (_up); \
+ (_op)->hints = (_hints); \
+ (_op)->ctx = (_ctx); \
+ } while(0)
+
+#endif
+
+/*
+ * Local variables:
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * End:
+ *
+ * vim: ts=8 sts=4 sw=4 expandtab
+ */
Added: trunk/code/src/gsl/include/gs-opcache.h
===================================================================
--- trunk/code/src/gsl/include/gs-opcache.h (rev 0)
+++ trunk/code/src/gsl/include/gs-opcache.h 2009-04-28 22:08:00 UTC (rev 458)
@@ -0,0 +1,52 @@
+
+#ifndef __GS_OPCACHE_H__
+#define __GS_OPCACHE_H__
+
+#include "gs.h"
+#include "gs-op.h"
+
+struct gs_op
+{
+ int index;
+ void (*callback)(void *ptr, int ret);
+ void *user_ptr;
+ gs_hints_t hints;
+ gs_context_t ctx;
+ gs_op_id_t id;
+ struct gs_list_head link;
+};
+
+typedef struct gs_opcache *gs_opcache_t;
+
+#define gs_op_entry(_op, _type, _member) \
+ ((_type *)((char *)(_op) - (unsigned long)((&((_type *)0)->_member))))
+
+#define GS_OPCACHE_INIT(_optype, _member, _size, _name) \
+ gs_opcache_init(sizeof(_optype), (int)(&((_optype *)0)->_member), _size, (_name))
+
+int gs_opcache_init(int typesize, int member_offset, int init_size, gs_opcache_t *cache);
+
+int gs_opcache_double_size(gs_opcache_t cache);
+
+int gs_opcache_destroy(gs_opcache_t cache);
+
+struct gs_op *gs_opcache_get(gs_opcache_t cache);
+
+int gs_opcache_put(gs_opcache_t cache, struct gs_op *op);
+
+inline int gs_opcache_size(gs_opcache_t cache);
+
+inline int gs_opcache_count(gs_opcache_t cache);
+
+struct gs_op *gs_opcache_lookup(gs_opcache_t cache, int id);
+
+#endif
+
+/*
+ * Local variables:
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * End:
+ *
+ * vim: ts=8 sts=4 sw=4 expandtab
+ */
Modified: trunk/code/src/gsl/include/gs.h
===================================================================
--- trunk/code/src/gsl/include/gs.h 2009-04-28 16:16:51 UTC (rev 457)
+++ trunk/code/src/gsl/include/gs.h 2009-04-28 22:08:00 UTC (rev 458)
@@ -6,10 +6,13 @@
#include <stdint.h>
#include <assert.h>
-#define GS_MAX_APIS 255
+#define GS_ERR_MASK (1 << 7)
+#define GS_ECANCELLED (GS_ERR_MASK | 1)
+#define GS_MAX_RESOURCES 255
+
#define GS_API_MASK (((uint64_t)0xFF)<<56)
-#define GS_GET_API_MASK(api_id) (GS_API_MASK&(((uint64_t)api_id)<<56))
+#define GS_GET_API_MASK(resource_id) (GS_API_MASK&(((uint64_t)resource_id)<<56))
#define GS_GET_API_ID(op_id) (((op_id&GS_API_MASK)>>56)&0xFF)
#ifdef __GS_POSIX_LOCKING__
@@ -27,8 +30,8 @@
typedef uint64_t gs_op_id_t;
-gs_op_id_t gs_id_gen(int api_id, uint64_t ptr);
-uint64_t gs_id_lookup(gs_op_id_t id, int *api_id);
+gs_op_id_t gs_id_gen(int resource_id, uint64_t ptr);
+uint64_t gs_id_lookup(gs_op_id_t id, int *resource_id);
#ifdef __GS_POSIX_LOCKING__
@@ -37,13 +40,34 @@
#define gs_mutex_unlock(__mut) pthread_mutex_unlock(__mut)
#define GS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
+typedef pthread_cond_t gs_cond_t;
+typedef pthread_condattr_t gs_condattr_t;
+#define gs_cond_init(__cond, __condattr) pthread_cond_init(__cond, __condattr)
+#define gs_cond_signal(__cond) pthread_cond_signal(__cond)
+#define gs_cond_broadcast(__cond) pthread_cond_broadcast(__cond)
+#define gs_cond_wait(__cond, __mutex) pthread_cond_wait(__cond, __mutex)
+#define gs_cond_timedwait(__cond, __mutex, __time) pthread_cond_timedwait(__cond, __mutex, __time)
+#define gs_cond_destroy(__cond) pthread_cond_destroy(__cond)
+
#else
typedef int gs_mutex_t;
static inline int gs_mutex_lock(gs_mutex_t *__mut) { return 0; }
static inline int gs_mutex_unlock(gs_mutex_t *__mut) { return 0; }
-static int GS_MUTEX_INITIALIZER = 0;
+#define GS_MUTEX_INITIALIZER 0
+typedef int gs_cond_t;
+typedef int gs_condattr_t;
+#define GS_COND_INITIALIZER 0
+
+static inline int gs_cond_init(gs_cond_t *__cond, gs_condattr_t *__condattr) { return 0; }
+static inline int gs_cond_signal(gs_cond_t *__cond) { return 0; }
+static inline int gs_cond_broadcast(gs_cond_t *__cond) { return 0; }
+static inline int gs_cond_wait(gs_cond_t *__cond, gs_mutex_t *__mutex) { return 0; }
+static inline int gs_cond_timedwait(
+ gs_cond_t *__cond, gs_mutex_t *__mutex, struct timespec *abstime) { return 0; }
+static inline int gs_cond_destroy(gs_cond_t *__cond) { return 0; }
+
#endif
struct gs_ctl
@@ -60,15 +84,16 @@
int in_pwait;
};
-struct gs_api
+struct gs_resource
{
- char *api_name;
+ char *resource_name;
int (*test)(gs_op_id_t id, int ms_timeout);
int (*poll_context)(gs_context_t context, int ms_timeout);
int (*cancel)(gs_op_id_t id);
+ int (*register_context)(gs_context_t context);
};
-int gs_register_api(struct gs_api *api);
+int gs_register_resource(struct gs_resource *resource);
int gs_cancel_op(gs_op_id_t op_id);
@@ -77,4 +102,21 @@
void gs_assert(const char *str, int expr);
+int gs_poll(gs_context_t context, int ms);
+
+#include <sys/time.h>
+
+#define GS_REL_MSECS_TO_ABS_TIMESPEC(__msecs, __abs) \
+ do { \
+ struct timeval __now; \
+ gettimeofday(&__now, NULL); \
+ __abs.tv_sec = __now.tv_sec + (int)(__msecs / 1e3); \
+ __abs.tv_nsec = (__now.tv_usec * 1e3) + ((__msecs % 1000) * 1e6); \
+ if(__abs.tv_nsec >= 1e9) \
+ { \
+ __abs.tv_sec++; \
+ __abs.tv_nsec -= 1e9; \
+ } \
+ } while(0)
+
#endif
Added: trunk/code/src/gsl/resources/mpi/Makefile
===================================================================
--- trunk/code/src/gsl/resources/mpi/Makefile (rev 0)
+++ trunk/code/src/gsl/resources/mpi/Makefile 2009-04-28 22:08:00 UTC (rev 458)
@@ -0,0 +1,14 @@
+
+MPI=${HOME}/dev/INSTALL-mpich2
+
+all: impl
+
+clean: ;
+ rm -f $(allobjs) $(alltests)
+
+impl: gs-mpi.o
+
+gs-mpi.o: gs-mpi.c gs-mpi.h
+ $(CC) -Wall -I../../include -I${MPI}/include -g -c -o $@ $<
+
+
Added: trunk/code/src/gsl/resources/mpi/gs-mpi.c
===================================================================
--- trunk/code/src/gsl/resources/mpi/gs-mpi.c (rev 0)
+++ trunk/code/src/gsl/resources/mpi/gs-mpi.c 2009-04-28 22:08:00 UTC (rev 458)
@@ -0,0 +1,400 @@
+
+#include <stdlib.h>
+#include <errno.h>
+#include "gs.h"
+#include "gs-opcache.h"
+#include "gs-hash.h"
+#include "gs-mpi.h"
+
+#define MPI_TESTCOUNT_MAXSIZE 1024
+
+struct mpi_op
+{
+ MPI_Request *request;
+ MPI_Status *status;
+ gs_op_id_t op_id;
+ struct gs_op op;
+};
+
+static gs_opcache_t mpi_opcache;
+static GS_LIST_HEAD(mpi_oplist);
+static gs_mutex_t oplist_mutex = GS_MUTEX_INITIALIZER;
+
+static MPI_Request *reqarray;
+static int *indexarray;
+static MPI_Status *statusarray;
+static int array_size = MPI_TESTCOUNT_MAXSIZE;
+static int array_count = 0;
+static gs_mutex_t array_mutex = GS_MUTEX_INITIALIZER;
+
+static gs_mutex_t wait_mutex = GS_MUTEX_INITIALIZER;
+static gs_cond_t wait_cond;
+
+static int gs_mpi_id;
+
+static int ops_in_progress = 0;
+
+static int mpi_initialized = 0;
+
+struct gs_api gs_mpi_api;
+
+int gs_mpi_init(void)
+{
+ int ret;
+
+ ret = GS_OPCACHE_INIT(struct mpi_op, op, array_size, &mpi_opcache);
+ if(ret != 0)
+ {
+ return ret;
+ }
+
+ reqarray = malloc(sizeof(*reqarray) * array_size);
+ if(!reqarray)
+ {
+ gs_opcache_destroy(mpi_opcache);
+ return -ENOMEM;
+ }
+
+ indexarray = malloc(sizeof(*indexarray) * array_size);
+ if(!indexarray)
+ {
+ gs_opcache_destroy(mpi_opcache);
+ free(reqarray);
+ return -ENOMEM;
+ }
+
+ statusarray = malloc(sizeof(*statusarray) * array_size);
+ if(!statusarray)
+ {
+ free(indexarray);
+ gs_opcache_destroy(mpi_opcache);
+ free(reqarray);
+ return -ENOMEM;
+ }
+
+ gs_cond_init(&wait_cond, NULL);
+
+ gs_mpi_id = gs_register_api(&gs_mpi_api);
+
+ mpi_initialized = 1;
+
+ return 0;
+}
+
+int gs_mpi_finalize(void)
+{
+ struct gs_op *op, *tmp;
+ struct mpi_op *mpi_op;
+
+ mpi_initialized = 0;
+
+ gs_mutex_lock(&oplist_mutex);
+ /* we need to cancel and cleanup all pending MPI operations */
+ gs_list_for_each_entry_safe(op, tmp, &mpi_oplist, link)
+ {
+ mpi_op = gs_op_entry(op, struct mpi_op, op);
+ ret = MPI_Cancel(mpi_op->request);
+ if(ret == MPI_ERR_REQUEST || ret == MPI_ERR_ARG)
+ {
+ gs_mutex_unlock(&oplist_mutex);
+ return -EINVAL;
+ }
+ }
+
+ while(!gs_list_empty(&mpi_oplist))
+ {
+ gs_mpi_poll(
+
+
+ gs_mutex_unlock(&oplist_mutex);
+
+
+ free(reqarray);
+ free(indexarray);
+ free(statusarray);
+ gs_opcache_destroy(mpi_opcache);
+ return 0;
+}
+
+static int double_array_size(void)
+{
+ gs_mutex_lock(&array_mutex);
+ array_size *= 2;
+ reqarray = realloc(reqarray, sizeof(*reqarray) * array_size);
+ if(!reqarray)
+ {
+ gs_mutex_unlock(&array_mutex);
+ return -ENOMEM;
+ }
+
+ indexarray = realloc(indexarray, sizeof(*indexarray) * array_size);
+ if(!indexarray)
+ {
+ gs_mutex_unlock(&array_mutex);
+ return -ENOMEM;
+ }
+ statusarray = realloc(statusarray, sizeof(*statusarray) * array_size);
+ if(!statusarray)
+ {
+ gs_mutex_unlock(&array_mutex);
+ return -ENOMEM;
+ }
+ gs_mutex_unlock(&array_mutex);
+ return 0;
+}
+
+static int add_op(MPI_Request req,
+ MPI_Status *status,
+ void (*callback)(void *ptr, int ret),
+ void *up,
+ gs_hints_t hints,
+ gs_context_t ctx)
+{
+ struct mpi_op *mpi_op;
+ struct gs_op *op;
+
+ op = gs_opcache_get(mpi_opcache);
+
+ /* kind of a hack for mpi case, if size of opcache doubles, we double
+ * the request and index arrays too
+ */
+ if(gs_opcache_size(mpi_opcache) > array_size)
+ {
+ double_array_size();
+ }
+
+ mpi_op = gs_op_entry(op, struct mpi_op, op);
+ mpi_op->status = status;
+
+ gs_op_fill(op, callback, up, hints, ctx);
+
+ mpi_op->op_id = gs_id_gen(gs_mpi_id, (uint64_t)(op->cache_id));
+ reqarray[op->cache_id] = req;
+ mpi_op->request = &(reqarray[op->cache_id]);
+ gs_mutex_lock(&oplist_mutex);
+ gs_list_add(&op->link, &mpi_oplist);
+ gs_mutex_unlock(&oplist_mutex);
+ return mpi_op->op_id;
+}
+
+#define DEFINE_MPISEND_CALL(__CALL__) \
+int gs_mpi_##__CALL__##_post( \
+ void *buffer, \
+ int count, \
+ MPI_Datatype datatype, \
+ int dest, \
+ int tag, \
+ MPI_Comm comm, \
+ void (*callback)(void *ptr, int ret), \
+ void *user_ptr, \
+ gs_hints_t hints, \
+ gs_context_t ctx, \
+ gs_op_id_t *op_id) \
+{ \
+ int ret; \
+ MPI_Request request; \
+ \
+ if(!mpi_initialized) \
+ { \
+ callback(user_ptr, -GS_ECANCELLED); \
+ return GS_COMPLETED; \
+ } \
+ \
+ ret = MPI_I##__CALL__( \
+ buffer, \
+ count, \
+ datatype, \
+ dest, \
+ tag, \
+ comm, \
+ &request); \
+ if(ret != MPI_SUCCESS) \
+ { \
+ callback(user_ptr, ret); \
+ return GS_COMPLETED; \
+ } \
+ \
+ *op_id = add_op(request, NULL, callback, user_ptr, hints, ctx); \
+ if(ops_in_progress == 0) \
+ { \
+ gs_mutex_lock(&wait_mutex); \
+ ops_in_progress = 1; \
+ gs_cond_signal(&wait_cond); \
+ gs_mutex_unlock(&wait_mutex); \
+ } \
+ return GS_POSTED; \
+}
+
+DEFINE_MPISEND_CALL(send);
+DEFINE_MPISEND_CALL(bsend);
+DEFINE_MPISEND_CALL(ssend);
+DEFINE_MPISEND_CALL(rsend);
+
+int gs_mpi_recv_post(
+ void *buf,
+ int count,
+ MPI_Datatype type,
+ int source,
+ int tag,
+ MPI_Comm comm,
+ MPI_Status *status,
+ void (*callback)(void *ptr, int ret),
+ void *user_ptr,
+ gs_hints_t hints,
+ gs_context_t ctx,
+ gs_op_id_t *op_id)
+{
+ int ret;
+ MPI_Request request;
+
+ ret = MPI_Irecv(buf, count, type, source, tag, comm, &request);
+ if(ret != MPI_SUCCESS)
+ {
+ callback(user_ptr, ret);
+ return GS_POSTED;
+ }
+
+ *op_id = add_op(request, status, callback, user_ptr, hints, ctx);
+ if(ops_in_progress == 0)
+ {
+ gs_mutex_lock(&wait_mutex);
+ ops_in_progress = 1;
+ gs_cond_signal(&wait_cond);
+ gs_mutex_unlock(&wait_mutex);
+ }
+ return GS_POSTED;
+}
+
+static int gs_mpi_poll(gs_context_t context, int millisecs)
+{
+ int ret, outcount, test_count;
+ struct timespec t;
+ struct gs_op *op;
+ struct mpi_op *mpi_op;
+
+ test_count = gs_opcache_count(mpi_opcache);
+
+ /* Wait for completion of operations */
+ ret = MPI_Waitsome(test_count, reqarray, &outcount, indexarray, statusarray);
+
+ /* According to MPI spec, if all requests in reqarray are null, outcount is
+ * set to MPI_UNDEFINED. This happens every time we poll without any operations
+ * in-progress. So we do a timedwait until the timeout passed in or until the
+ * condition is signalled by the addition of an operation.
+ */
+ if(outcount == MPI_UNDEFINED)
+ {
+ gs_mutex_lock(&wait_mutex);
+
+ /* Verify that no ops are posted with lock held. This prevents us from missing
+ * a signal from a post.
+ */
+ ret = MPI_Waitsome(array_count, reqarray, &outcount, indexarray, statusarray);
+ if(outcount == MPI_UNDEFINED)
+ {
+ /* ok, no ops posted, so we can wait */
+ ops_in_progress = 0;
+
+ /* timedwait takes absolute time */
+ GS_REL_MSECS_TO_ABS_TIMESPEC(millisecs, t);
+ ret = gs_cond_timedwait(&wait_cond, &wait_mutex, &t);
+ if(ret != 0)
+ {
+ /* we assume timedout or was interrupted by a signal */
+ gs_mutex_unlock(&wait_mutex);
+ return ret;
+ }
+
+ /* we're here so ops are in progress and we must test for completion */
+ ret = MPI_Waitsome(array_count, reqarray, &outcount, indexarray, statusarray);
+ assert(outcount != MPI_UNDEFINED);
+ }
+ gs_mutex_unlock(&wait_mutex);
+ }
+
+ if(ret == MPI_SUCCESS || ret == MPI_ERR_IN_STATUS)
+ {
+ int i;
+ for(i = 0; i < outcount; ++i)
+ {
+ int mpi_errno;
+
+ if(reqarray[indexarray[i]] == MPI_REQUEST_NULL)
+ {
+ int cancelled;
+ MPI_Test_cancelled(&statusarray[i], &cancelled);
+ if(cancelled)
+ {
+ mpi_errno = -GS_ECANCELLED;
+ }
+ else
+ {
+ mpi_errno = statusarray[i].MPI_ERROR;
+ }
+
+ op = gs_opcache_lookup(mpi_opcache, indexarray[i]);
+ mpi_op = gs_op_entry(op, struct mpi_op, op);
+ if(mpi_op->status)
+ {
+ memcpy((mpi_op->status), &(statusarray[i]), sizeof(MPI_Status));
+ }
+
+ /* call the callback */
+ gs_invoke_callback(op, mpi_errno);
+
+ /* remove the op from the operation list */
+ gs_mutex_lock(&oplist_mutex);
+ gs_list_del(&op->link);
+ gs_mutex_unlock(&oplist_mutex);
+
+ /* give the op back to the opcache */
+ gs_opcache_put(mpi_opcache, op);
+ }
+ }
+ }
+ else
+ {
+ return ret;
+ }
+
+ return 0;
+}
+
+static int gs_mpi_cancel(gs_op_id_t op_id)
+{
+ uint64_t cache_id;
+ int api_id, ret;
+ struct gs_op *op;
+ struct mpi_op *mpi_op;
+
+ cache_id = gs_id_lookup(op_id, &api_id);
+ assert(api_id == gs_mpi_id);
+
+ op = gs_opcache_lookup(mpi_opcache, (int)cache_id);
+ mpi_op = gs_op_entry(op, struct mpi_op, op);
+
+ ret = MPI_Cancel(mpi_op->request);
+ if(ret == MPI_ERR_REQUEST || ret == MPI_ERR_ARG)
+ {
+ return -EINVAL;
+ }
+ return 0;
+}
+
+struct gs_api gs_mpi_api =
+{
+ "mpi",
+ NULL,
+ gs_mpi_poll,
+ gs_mpi_cancel,
+ gs_mpi_context_register
+};
+
+/*
+ * Local variables:
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * End:
+ *
+ * vim: ts=8 sts=4 sw=4 expandtab
+ */
Added: trunk/code/src/gsl/resources/mpi/gs-mpi.gsh
===================================================================
--- trunk/code/src/gsl/resources/mpi/gs-mpi.gsh (rev 0)
+++ trunk/code/src/gsl/resources/mpi/gs-mpi.gsh 2009-04-28 22:08:00 UTC (rev 458)
@@ -0,0 +1,31 @@
+#ifndef __GS_MPI_GSH__
+#define __GS_MPI_GSH__
+
+#include "gs.h"
+#include "mpi.h"
+
+/* The return values of these functions match their blocking
+ * counterparts, except that they may be negative, which indicate
+ * an error during the post of the call. I.e. -ENOMEM indicates
+ * malloc failed in the post. Also, the function may be cancelled
+ * at some point, and to indicate that it was cancelled, a special
+ * GS errno value is returned: -GS_ECANCELLED.
+ */
+
+/* Matches the MPI_Isend call. The return value of this function
+ * will either be from MPI_Send or MPI_Isend. */
+__blocking int gs_mpi_send(void *, int, MPI_Datatype, int, int, MPI_Comm);
+
+/* Matches the MPI_Ibsend call */
+__blocking int gs_mpi_bsend(void *, int, MPI_Datatype, int, int, MPI_Comm);
+
+/* Matches the MPI_Issend call */
+__blocking int gs_mpi_ssend(void *, int, MPI_Datatype, int, int, MPI_Comm);
+
+/* Matches the MPI_Irsend call */
+__blocking int gs_mpi_rsend(void *, int, MPI_Datatype, int, int, MPI_Comm);
+
+/* Matches the MPI_Irecv call */
+__blocking int gs_mpi_recv(void *, int, MPI_Datatype, int, int, MPI_Comm, MPI_Status *);
+
+#endif
Added: trunk/code/src/gsl/resources/mpi/gs-mpi.h
===================================================================
--- trunk/code/src/gsl/resources/mpi/gs-mpi.h (rev 0)
+++ trunk/code/src/gsl/resources/mpi/gs-mpi.h 2009-04-28 22:08:00 UTC (rev 458)
@@ -0,0 +1,9 @@
+#ifndef __GS_MPI_H__
+#define __GS_MPI_H__
+
+#include "mpi.h"
+
+int gs_mpi_init(void);
+int gs_mpi_finalize(void);
+
+#endif
Added: trunk/code/src/gsl/resources/mpi/test/Makefile
===================================================================
--- trunk/code/src/gsl/resources/mpi/test/Makefile (rev 0)
+++ trunk/code/src/gsl/resources/mpi/test/Makefile 2009-04-28 22:08:00 UTC (rev 458)
@@ -0,0 +1,29 @@
+
+MPI=${HOME}/dev/INSTALL-mpich2/
+GS=../../..
+
+gsfiles=send-recv.gs
+
+tests=$(patsubst %.gs,%,$(gsfiles))
+objs=$(patsubst %.gs,%.gs.o,$(gsfiles))
+cpps=$(patsubst %.gs,%.gs.gsi,$(gsfiles))
+trans=$(patsubst %.gs,%.gs.i,$(gsfiles))
+
+all: $(tests)
+
+clean: ;
+ rm -f $(objs) $(tests) $(trans) $(cpps)
+
+%.gs: ;
+
+$(cpps): %.gs.gsi: %.gs
+ $(CC) -I${MPI}/include -I.. -I${GS}/include -x c -E $< -o $@
+
+$(trans): %.gs.i: %.gs.gsi
+ ${GS}/gs-parser -p $< > $@
+
+$(objs): %.gs.o: %.gs.i
+ ${MPI}/bin/mpicc -g -x c -c -o $@ $<
+
+$(tests): %: %.gs.o
+ ${MPI}/bin/mpicc -o $@ $< ../gs-mpi.o -L${GS}/common -lgs
Added: trunk/code/src/gsl/resources/mpi/test/send-recv.gs
===================================================================
--- trunk/code/src/gsl/resources/mpi/test/send-recv.gs (rev 0)
+++ trunk/code/src/gsl/resources/mpi/test/send-recv.gs 2009-04-28 22:08:00 UTC (rev 458)
@@ -0,0 +1,65 @@
+
+#include "gs.h"
+#include "gs-mpi.gsh"
+#include <stdio.h>
+
+__blocking int send_recv(int numprocs, int rank)
+{
+ char buf[1024];
+ char recvbuf[1024];
+ MPI_Status status;
+ int recvsize;
+ int ret;
+
+ sprintf(buf, "hello from %d!", rank);
+
+ pwait
+ {
+ pbranch
+ {
+ ret = gs_mpi_send(
+ buf, strlen(buf), MPI_CHAR, (rank+1)%numprocs, 10, MPI_COMM_WORLD);
+ printf("%d: sent message to %d\n", rank, (rank+1)%numprocs);
+ }
+
+ pbranch
+ {
+ printf("%d: receiving message from %d\n", rank, (numprocs+(rank-1))%numprocs);
+ ret = gs_mpi_recv(
+ recvbuf, 1024, MPI_CHAR, (numprocs+(rank-1))%numprocs, 10, MPI_COMM_WORLD, &status);
+ }
+ }
+ MPI_Get_count(&status, MPI_CHAR, &recvsize);
+
+ printf("%d: received message from %d: %.*s\n", rank, (numprocs+rank-1)%numprocs, recvsize, recvbuf);
+
+ return 0;
+}
+
+int done = 0;
+
+void done_callback(void *user_ptr, int ret)
+{
+ done = 1;
+}
+
+int main(int argc, char *argv[])
+{
+ int numprocs, rank;
+ gs_op_id_t op_id;
+
+ MPI_Init(&argc, &argv);
+
+ MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+
+ gs_mpi_init();
+
+ send_recv_post(numprocs, rank, done_callback, NULL, NULL, NULL, &op_id);
+ while(done == 0)
+ {
+ gs_poll(NULL, 10);
+ }
+ MPI_Finalize();
+ return 0;
+}
Added: trunk/code/src/gsl/resources/timer/Makefile
===================================================================
--- trunk/code/src/gsl/resources/timer/Makefile (rev 0)
+++ trunk/code/src/gsl/resources/timer/Makefile 2009-04-28 22:08:00 UTC (rev 458)
@@ -0,0 +1,10 @@
+
+objs=gs-timer.o
+
+all: $(objs)
+
+clean: ;
+ rm -f $(objs)
+
+%.o: %.c
+ $(CC) -Wall -I../../include -g -c -o $@ $<
Added: trunk/code/src/gsl/resources/timer/gs-timer.c
===================================================================
--- trunk/code/src/gsl/resources/timer/gs-timer.c (rev 0)
+++ trunk/code/src/gsl/resources/timer/gs-timer.c 2009-04-28 22:08:00 UTC (rev 458)
@@ -0,0 +1,183 @@
+
+#define TIMER_DEFAULT_SIZE 1024
+
+static gs_opcache_t timer_opcache;
+static GS_LIST_HEAD(timer_list);
+
+struct timer_op
+{
+ struct timeval;
+ gs_op op;
+};
+
+int gs_timer_init(void)
+{
+ ret = GS_OPCACHE_INIT(struct timer_op, op, TIMER_DEFAULT_SIZE, &timer_opcache);
+ return ret;
+}
+
+int gs_timer_finalize(void)
+{
+ gs_opcache_destroy(timer_opcache);
+ return 0;
+}
+
+int gs_timer_post(
+ int millisecs,
+ void (*callback)(void *ptr, int ret),
+ void *user_ptr,
+ gs_hints_t hints,
+ gs_context_t ctx,
+ gs_op_id_t *op_id)
+{
+ struct timeval adjust, now;
+ struct gs_op *op;
+ struct timer_op *top;
+ struct gs_list_head *iter, *holder;
+ struct gs_op *gs_op_iter;
+ struct timer_op *timer_op_iter;
+
+ op = gs_opcache_get(timer_opcache);
+ gs_op_fill(op, callback, user_ptr, hints, ctx);
+
+ top = gs_op_entry(op, struct timer_op, op);
+
+ adjust.tv_sec = (int)(millisecs / 1e3);
+ adjust.tv_usec = (millisecs % 1000) * 1e3;
+ gettimeofday(&now, NULL);
+ timeradd(&adjust, &now, &(top->timer));
+
+ gs_mutex_lock(&timer_mutex);
+ holder = &timer_list;
+ gs_list_for_each(iter, &timer_list)
+ {
+ gs_op_iter = gs_list_get_entry(iter, struct gs_op, link);
+ timer_op_iter = gs_op_entry(gs_op_iter, struct timer_op, op);
+
+ if(timercmp(&(top->timer), &(timer_op_iter->timer), <))
+ {
+ break;
+ }
+ holder = iter;
+ }
+ gs_list_add(top, holder);
+ gs_mutex_unlock(&timer_mutex);
+ return 0;
+
+}
+
+static int gs_mpi_poll(gs_context_t context, int millisecs)
+{
+ struct gs_list_head *entry;
+ struct gs_op *gop;
+ struct timer_op *top;
+ struct timeval adjust, now, diff;
+ struct timespec ts_diff, rem;
+ int ret, ns_errno;
+
+ gs_mutex_lock(&timer_mutex);
+ entry = gs_list_peek(&timer_list);
+ if(entry)
+ {
+ gop = gs_list_get_entry(entry, struct gs_op, link);
+ top = gs_op_entry(gop, struct timer_op, op);
+ }
+
+ gettimeofday(&now, NULL);
+
+ /* complete the timers that have hit (t < now) */
+ while(entry && timercmp(&(top->timer), &now, <))
+ {
+
+ /* what sort of errors could we return? */
+
+ /* this timer has hit, so we pop and call callback */
+ entry = gs_list_pop(&timer_list);
+ gs_invoke_callback(gop, 0);
+
+ /* give the op back to the opcache */
+ gop = gs_list_get_entry(entry, struct gs_op, link);
+ gs_opcache_put(timer_opcache, gop);
+
+ /* setup for next iteration */
+ entry = gs_list_peek(&timer_list);
+ if(entry)
+ {
+ gop = gs_list_get_entry(entry, struct gs_op, link);
+ top = gs_op_entry(gop, struct timer_op, op);
+ }
+ }
+
+ adjust.tv_sec = (int)(millisecs / 1e3);
+ adjust.tv_usec = (millisecs % 1000) * 1e3;
+ timeradd(&now, &adjust, &timeout);
+
+ entry = gs_list_peek(&timer_list);
+ if(entry)
+ {
+ gop = gs_list_get_entry(entry, struct gs_op, link);
+ top = gs_op_entry(gop, struct timer_op, op);
+ }
+
+ /* sleep for timers that will hit before timeout is reached (t < (now+millisecs)) */
+ while(entry && timercmp(&(top->timer), &timeout, <))
+ {
+ gettimeofday(&now, NULL);
+ timersub(&(top->timer), &now, &diff);
+ TIMEVAL_TO_TIMESPEC(&diff, &ts_diff);
+
+ /* this timer will hit before the timeout is reached, so we pop, sleep,
+ * and call callback */
+ entry = gs_list_pop(&timer_list);
+ ret = nanosleep(&ts_diff, &rem);
+ if(ret != 0)
+ {
+ gs_invoke_callback(gop, errno);
+ gs_mutex_unlock(&timer_mutex);
+ return -EINTR;
+ }
+
+ /* give the op back to the opcache */
+ gop = gs_list_get_entry(entry, struct gs_op, link);
+ gs_opcache_put(timer_opcache, gop);
+
+ /* setup for next iteration */
+ entry = gs_list_peek(&timer_list);
+ if(entry)
+ {
+ gop = gs_list_get_entry(entry, struct gs_op, link);
+ top = gs_op_entry(gop, struct timer_op, op);
+ }
+ }
+
+ /* no more timers within this timeout window. sleep for the rest of the timeout */
+ gettimeofday(&now, NULL);
+ timersub(&timeout, &now, &diff);
+ TIMEVAL_TO_TIMESPEC(&diff, &ts_diff);
+ nanosleep(&ts_diff, &rem);
+
+ gs_mutex_unlock(&timer_mutex);
+
+ return 0;
+}
+
+static int gs_timer_cancel(gs_op_id_t op_id)
+{
+}
+
+struct gs_api gs_mpi_api =
+{
+ "timer",
+ NULL,
+ gs_timer_poll,
+ gs_timer_cancel
+};
+
+/*
+ * Local variables:
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * End:
+ *
+ * vim: ts=8 sts=4 sw=4 expandtab
+ */
Added: trunk/code/src/gsl/resources/timer/gs-timer.gsh
===================================================================
--- trunk/code/src/gsl/resources/timer/gs-timer.gsh (rev 0)
+++ trunk/code/src/gsl/resources/timer/gs-timer.gsh 2009-04-28 22:08:00 UTC (rev 458)
@@ -0,0 +1,9 @@
+#ifndef __GS_TIMER_GSH__
+#define __GS_TIMER_GSH__
+
+#include "gs.h"
+
+__blocking int gs_timer(int millisecs);
+
+#endif
+
Added: trunk/code/src/gsl/resources/timer/gs-timer.h
===================================================================
--- trunk/code/src/gsl/resources/timer/gs-timer.h (rev 0)
+++ trunk/code/src/gsl/resources/timer/gs-timer.h 2009-04-28 22:08:00 UTC (rev 458)
@@ -0,0 +1,7 @@
+#ifndef __GS_TIMER_H__
+#define __GS_TIMER_H__
+
+int gs_timer_init(void);
+int gs_timer_finalize(void);
+
+#endif
Modified: trunk/code/src/gsl/tests/correctness/Makefile
===================================================================
--- trunk/code/src/gsl/tests/correctness/Makefile 2009-04-28 16:16:51 UTC (rev 457)
+++ trunk/code/src/gsl/tests/correctness/Makefile 2009-04-28 22:08:00 UTC (rev 458)
@@ -53,7 +53,7 @@
${GSCC} $< $@
$(alltests): %: %.gs.o btest-impl.o
- $(CC) -rdynamic -o $@ $< btest-impl.o -L../.. -lgs
+ $(CC) -rdynamic -o $@ $< btest-impl.o -L../../common -lgs
runtests: $(tests) runargstests
@for t in $(tests); do \
Modified: trunk/code/src/gsl/tests/correctness/forloop.gs
===================================================================
--- trunk/code/src/gsl/tests/correctness/forloop.gs 2009-04-28 16:16:51 UTC (rev 457)
+++ trunk/code/src/gsl/tests/correctness/forloop.gs 2009-04-28 22:08:00 UTC (rev 458)
@@ -5,9 +5,11 @@
__blocking void run_forloop(void)
{
int i;
- int a = 0;
+ int a;
int ret;
+ a = random();
+
for(i = 0; i < 100; ++i)
{
ret = btest1(&a);
@@ -19,7 +21,10 @@
ret = btest3(&a);
assert(ret == 0);
assert(a == (i*6+6));
+ if(i == 10)
+ break;
}
+
}
static int done = 0;
Modified: trunk/code/src/gsl/tests/correctness/parallel1.gs
===================================================================
--- trunk/code/src/gsl/tests/correctness/parallel1.gs 2009-04-28 16:16:51 UTC (rev 457)
+++ trunk/code/src/gsl/tests/correctness/parallel1.gs 2009-04-28 22:08:00 UTC (rev 458)
@@ -4,6 +4,7 @@
__blocking void run_par1(void)
{
+ int shared = 0;
int a = 0, b = 0, c = 0;
int ret1, ret2, ret3;
@@ -14,12 +15,14 @@
ret1 = btest1(&a);
assert(ret1 == 0);
assert(a == 1);
+ shared = 1;
}
pbranch
{
ret2 = btest2(&b);
assert(ret2 == 0);
+ shared = 2;
assert(b == 2);
}
Modified: trunk/code/src/gsl/tests/correctness/parallelfor.gs
===================================================================
--- trunk/code/src/gsl/tests/correctness/parallelfor.gs 2009-04-28 16:16:51 UTC (rev 457)
+++ trunk/code/src/gsl/tests/correctness/parallelfor.gs 2009-04-28 22:08:00 UTC (rev 458)
@@ -5,22 +5,30 @@
{
int a[100];
int ret[100];
+ int i;
memset(a, 0, sizeof(int)*100);
memset(ret, 0, sizeof(int)*100);
- pwait
+ for(i = 0; i < 8; ++i)
{
- int i;
- for(i = 0; i < 100; ++i)
+ pwait
{
+ pcopy int i;
+ pbranch {
+ while(flow_buffer_not_done)
+ {
+ for(i = 0; i < 100; ++i)
+ {
pbranch
{
+ int j = i;
a[i] = i;
ret[i] = btest1(&a[i]);
assert(ret[i] == 0);
assert(a[i] == (i+1));
+ j = i;
ret[i] = btest2(&a[i]);
assert(ret[i] == 0);
assert(a[i] == (i+3));
1
0