[Gs-commits] Grayskull Repository branch, master, updated. git-migration-305-g80083cf
17 Dec
2009
17 Dec
'09
2:04 p.m.
A ref change was pushed to the repository containing
the project "Grayskull Repository".
The branch, master has been updated
via 80083cfdfe7b0950eec19f57a6ec12d8774c3351 (commit)
via db391c7a119b49f223bbe33cfa7e03027c63a766 (commit)
from 281aa78117f68ba1bc46ea6213767e56839a05cb (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 80083cfdfe7b0950eec19f57a6ec12d8774c3351
Author: Samuel Lang <[email protected]>
Date: Thu Dec 17 13:41:13 2009 -0600
some type infrastructure for remote encoding/decoding.
commit db391c7a119b49f223bbe33cfa7e03027c63a766
Author: Samuel Lang <[email protected]>
Date: Wed Dec 16 16:00:32 2009 -0600
fix examples/rpc-invoke.gs to work with latest shared/private features.
-----------------------------------------------------------------------
Summary of changes:
code/src/gsl/common/gs-buffer.h | 73 +++++
code/src/gsl/common/gs-count-list.h | 126 ++++++++
code/src/gsl/common/gs-debug.h | 16 +
code/src/gsl/common/gs-error.h | 86 ++++++
code/src/gsl/{include => common}/gs-hash.h | 0
code/src/gsl/common/gs-list.h | 230 +++++++++++++++
code/src/gsl/common/gs-node.h | 15 +
code/src/gsl/common/gs-safe-list.h | 161 ++++++++++
code/src/gsl/common/gs-types.h | 17 +
code/src/gsl/common/gs.h | 128 ++++++++
code/src/gsl/include/gs.h | 131 --------
code/src/gsl/parser/CGen.lhs | 4 +
code/src/gsl/parser/gs-blocking-parser.lhs | 17 +-
code/src/gsl/parser/gs-remote-parser.lhs | 8 +-
code/src/gsl/proto/gs-byteswap.h | 112 +++++++
code/src/gsl/proto/gs-encoding-pw.h | 442 ++++++++++++++++++++++++++++
code/src/gsl/proto/gs-encoding.h | 7 +
17 files changed, 1434 insertions(+), 139 deletions(-)
create mode 100644 code/src/gsl/common/gs-buffer.h
create mode 100644 code/src/gsl/common/gs-count-list.h
create mode 100644 code/src/gsl/common/gs-debug.h
create mode 100644 code/src/gsl/common/gs-error.h
rename code/src/gsl/{include => common}/gs-hash.h (100%)
create mode 100644 code/src/gsl/common/gs-list.h
create mode 100644 code/src/gsl/common/gs-node.h
create mode 100644 code/src/gsl/common/gs-safe-list.h
create mode 100644 code/src/gsl/common/gs-types.h
create mode 100644 code/src/gsl/common/gs.h
delete mode 100644 code/src/gsl/include/gs.h
create mode 100644 code/src/gsl/proto/gs-byteswap.h
create mode 100644 code/src/gsl/proto/gs-encoding-pw.h
create mode 100644 code/src/gsl/proto/gs-encoding.h
Diff of changes:
diff --git a/code/src/gsl/common/gs-buffer.h b/code/src/gsl/common/gs-buffer.h
new file mode 100644
index 0000000..5ee944e
--- /dev/null
+++ b/code/src/gsl/common/gs-buffer.h
@@ -0,0 +1,73 @@
+#ifndef __GS_BUFFER_H__
+#define __GS_BUFFER_H__
+
+#include <stdlib.h>
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#include "common/gs-types.h"
+
+/* We require a max size for a buffer, to prevent clients from requesting
+ * (perhaps due to a bug or bit-flip somewhere) more memory than is available
+ * on the machine.
+ */
+
+/**
+ * The buffer type is used for generic byte streams. A current pointer field
+ * is included allowing the buffer to be used by encoding/decoding mechanisms
+ * before being transmitted. The buffer type can be encoded itself, allowing
+ * it to be used as a generic buffer type.
+ */
+typedef struct
+{
+ void *buffer;
+ uint64_t size;
+ void *cptr;
+} gs_buffer_t;
+
+#define GS_BUFFER_STATIC_INITIALIZER() = { NULL, 0, NULL }
+
+#define gs_buffer_cptr(__buf) ((__buf)->cptr)
+
+static inline gs_ret_t gs_buffer_alloc(gs_buffer_t *buffer, int64_t size)
+{
+ (*buffer)->buffer = malloc(sizeof(*(*buffer)->buffer) * size);
+ if(!(*buffer)->buffer)
+ {
+ return gs_error_errno(ENOMEM);
+ }
+ (*buffer)->size = size;
+ gs_buffer_ptr_reset(buffer);
+ return GS_SUCCESS;
+}
+
+static inline void gs_buffer_free(gs_buffer_t *buffer)
+{
+ if(buffer && buffer->buffer) free(buffer->buffer);
+ buffer->buffer = NULL;
+ buffer->cptr = NULL;
+ buffer->size = 0;
+}
+
+static inline void gs_buffer_ptr_reset(gs_buffer_t *buffer)
+{
+ buffer->cptr = buffer->buffer;
+}
+
+/* The buffer_check_overflow macro verfies that the current buffer pointer is not
+ * at the end of the buffer, and that there's enough space left for __inc bytes.
+ */
+#define gs_buffer_check_overflow(__buf, __inc) do { \
+ if((__buf)->size < (((__buf)->cptr - (__buf)->buffer) + (__inc))) \
+ { \
+ return gs_error_errno(EOVERFLOW); \
+ } \
+} while(0)
+
+/* Increment the current buffer pointer */
+#define gs_buffer_inc(__buf, __inc) do { \
+ (__buf)->cptr+=(__inc); \
+} while(0)
+
+#endif /* __GS_BUFFER_H__ */
diff --git a/code/src/gsl/common/gs-count-list.h b/code/src/gsl/common/gs-count-list.h
new file mode 100644
index 0000000..1aec02c
--- /dev/null
+++ b/code/src/gsl/common/gs-count-list.h
@@ -0,0 +1,126 @@
+#ifndef __GS_COUNT_LIST_H__
+#define __GS_COUNT_LIST_H__
+
+#include "common/gs-list.h"
+
+typedef struct
+{
+ gs_list_t list;
+ uin64_t count;
+} gs_countlist_t;
+
+typedef struct
+{
+ gs_countlist_t *inlist;
+ struct gs_list_link link;
+} gs_countlist_link_t;
+
+#define GS_COUNT_LIST_NULL { { NULL, NULL }, 0 }
+
+#define GS_COUNT_LIST_STATIC_INITIALIZER(name) { { &(name), &(name) }, 0 }
+
+#define GS_COUNT_LIST_DEFINE(name) \
+ gs_countlist_t name = GS_COUNT_LIST_STATIC_INITIALIZER(name)
+
+#define gs_countlist_link_clear(__link) do { \
+ (__link)->inlist = NULL; \
+ gs_list_link_clear(&((__link)->link)); \
+} while(0)
+
+static inline void gs_countlist_init(gs_countlist_t *clist)
+{
+ gs_list_init(&clist->list);
+ clist->count = 0;
+}
+
+static inline void gs_countlist_add(
+ struct gs_countlist_link_t *new, gs_countlist_t *clist)
+{
+ assert(new->inlist == NULL);
+ assert(new->link.next == NULL && new->link.prev == NULL);
+ gs_list_add(&new->link, clist->list);
+ clist->count++;
+}
+
+static inline void gs_countlist_add_tail(
+ gs_countlist_link_t *new, gs_countlist_t *clist)
+{
+ assert(new->inlist == NULL);
+ assert(new->link.next == NULL && new->link.prev == NULL);
+ gs_list_add_tail(&new->link, clist->list);
+ clist->count++;
+}
+
+static inline void gs_countlist_del(
+ gs_countlist_link_t *entry, gs_countlist_t *clist)
+{
+ assert(entry->link.next != NULL && entry->link.prev != NULL);
+ assert(entry->inlist == clist);
+ gs_list_del(&entry->link);
+ clist->count--;
+ CLEAR_GS_LIST_LINK(entry->link);
+}
+
+static inline int gs_countlist_empty(gs_countlist_t *clist)
+{
+ return clist->count == 0;
+}
+
+#define gs_countlist_push(_op, _clist) gs_countlist_add_tail(_op, _clist)
+
+static inline gs_countlist_link_t *gs_countlist_pop(gs_countlist_t *list)
+{
+ struct gs_countlist_link *entry;
+ if(gs_countlist_empty(list)) return NULL;
+ entry = gs_list_get_entry(gs_list_pop(&list->list), gs_countlist_link_t, link);
+ countlist->count--;
+ CLEAR_GS_LIST_LINK(entry);
+ assert(((gs_countlist_t *)entry->inlist) == list);
+ entry->inlist = NULL;
+ return entry;
+}
+
+#define gs_countlist_peek(_list) \
+ gs_list_get_entry(gs_list_peek(&(_list)->list), gs_countlist_link_t, link)
+
+#define gs_countlist_get_entry(ptr, type, member) \
+ gs_list_get_entry(ptr, type, member)
+
+#define gs_countlist_link_from_list_link(_ptr) \
+ gs_list_get_entry(_ptr, gs_countlist_link_t, link)
+
+/* these are automatically safe for removal during iteration */
+
+#define gs_countlist_exists(clist, llink) gs_list_exists(&(clist->list), llink)
+
+#define gs_countlist_find(clist, compare, ptr) \
+ gs_countlist_find(&(clist->list), compare, ptr)
+
+#define gs_countlist_push(__list, __entry) gs_list_push(&(__list)->list, __entry)
+
+#define gs_countlist_pop(__list) gs_list_pop(&(__list)->list)
+
+#define gs_countlist_peek(__list) gs_list_peek(&(__list)->list)
+
+static inline uint64_t gs_countlist_size(gs_countlist_t *list)
+{
+ return list->count;
+}
+
+static inline gs_countlist_link_t *gs_countlist_find(
+ gs_countlist_t *list,
+ int (*compare)(struct gs_countlist_link_t *, void *),
+ void *ptr)
+{
+ struct gs_countlist_link_t *llink;
+ gs_countlist_for_each(llink, list)
+ {
+ if(compare(llink, list))
+ {
+ return llink;
+ }
+ }
+ return NULL;
+}
+
+#endif /* __GS_COUNT_LIST_H__ */
diff --git a/code/src/gsl/common/gs-debug.h b/code/src/gsl/common/gs-debug.h
new file mode 100644
index 0000000..d0e9481
--- /dev/null
+++ b/code/src/gsl/common/gs-debug.h
@@ -0,0 +1,16 @@
+enum gs_debug_mask
+{
+ GS_DEBUG_LEVEL0 = 0,
+ GS_DEBUG_LEVEL1 = 1,
+ GS_DEBUG_LEVEL2 = 2
+};
+
+/**
+ * Debugging is used by developers during development when writing code
+ * and debugging their code in distributed environments. It is not
+ * meant for providing information to end-users.
+ */
+uint32_t gs_debug(enum gs_debug_mask mask,
+ char *message);
+
+
diff --git a/code/src/gsl/common/gs-error.h b/code/src/gsl/common/gs-error.h
new file mode 100644
index 0000000..afe45d0
--- /dev/null
+++ b/code/src/gsl/common/gs-error.h
@@ -0,0 +1,86 @@
+#ifndef __GS_ERROR_H__
+#define __GS_ERROR_H__
+
+#define GS_ERR_MASK (1 << 7)
+#define GS_ECANCELLED (GS_ERR_MASK | 1)
+
+/**
+ * This struct is used internally by the gs_error_t type, defined below.
+ *
+ * The error message adds information useful to the consumer of the error
+ * (the user or administrator). Error messages are tagged with the location
+ * (the node) where the error message was added to the error structure.
+ * Error messages are optional! In order to maintain a lightweight error
+ * interface, error messages should only be added to errors where the error
+ * is clearly an unrecoverable error. The error interfaces provide constructs
+ * both for errors with and without messages.
+ */
+struct gs_error_message
+{
+ gs_node_t location;
+ gs_string_t *message;
+ gs_countlist_link_t link; /* we use countlist to allow for encoding */
+};
+
+/**
+ * The error type allows errors to be wrapped in an error type, useful
+ * for managing error codes, logging errors in a consistent format, and
+ * later finger-pointing of errors. This structure and the
+ * companion error interfaces should be used throughout the entire framework.
+ * Errors in responses should
+ * be in the gs_error_t format, and errors from resources and other components
+ * should use this type as well.
+ * The error structure consists of a single error code for the
+ * error, the source node where the error is generated, and optional error
+ * messages.
+ */
+typedef struct
+{
+ gs_node_t node;
+ int32_t error_code;
+ gs_countlist_t messages;
+} gs_error_t;
+
+typedef gs_error_t gs_ret_t;
+
+#define GS_SUCCESS { GS_NODE_NULL, GS_ERROR_NONE, GS_COUNT_LIST_NULL }
+
+/**
+ * Wrap an error code as a gs_error_t error. This will clear the
+ * other fields in the error, and set the node to the current
+ * node.
+ *
+ * This is a lightweight interface to
+ * construct a gs_error_t type, useful for recoverable errors.
+ */
+void gs_error_wrap(
+ int32_t error_code,
+ gs_error_t *error);
+
+/**
+ * Create a gs_error_t type from an error code, and include a message
+ * about the error. The message gets copied to the resulting error
+ * structure, so it can be freed after the error returns. The returned
+ * error structure is a heap variable, a companion call to gs_error_free
+ * is required.
+ */
+gs_error_t *gs_error_create(
+ int32_t error_code,
+ char *message /** An optional message to add to the error */);
+
+/**
+ * Add a message to the set of error messages within an error structure. This
+ * function allows for finger-pointing and path-following of
+ * errors that pass through multiple nodes. The current node is added
+ * with the message to the stack of messages.
+ */
+void gs_error_add_message(
+ gs_error_t *error,
+ char *message);
+
+/**
+ * Free an error that was created with gs_error_create.
+ */
+void gs_error_destroy(gs_error_t *error);
+
+#endif /* __GS_ERROR_H__ */
diff --git a/code/src/gsl/include/gs-hash.h b/code/src/gsl/common/gs-hash.h
similarity index 100%
rename from code/src/gsl/include/gs-hash.h
rename to code/src/gsl/common/gs-hash.h
diff --git a/code/src/gsl/common/gs-list.h b/code/src/gsl/common/gs-list.h
new file mode 100644
index 0000000..d2dc62f
--- /dev/null
+++ b/code/src/gsl/common/gs-list.h
@@ -0,0 +1,230 @@
+#ifndef __GS_LIST_H__
+#define __GS_LIST_H__
+
+#ifdef __STRICT_ANSI__
+#define inline __inline__
+#endif
+
+#include <stdlib.h>
+#include <assert.h>
+
+typedef struct gs_list_link gs_list_link_t;
+struct gs_list_link {
+ struct gs_list_link *next, *prev;
+};
+
+typedef gs_list_link_t gs_list_t;
+
+#define GS_LIST_STATIC_INITIALIZER(name) { &(name), &(name) }
+
+#define GS_LIST_DEFINE(name) \
+ gs_list_t name = GS_LIST_STATIC_INITIALIZER(name)
+
+static inline void gs_list_init(gs_list_t *list)
+{
+ list->next = (struct gs_list_link *)list;
+ list->prev = (struct gs_list_link *)list;
+}
+
+static inline void gs_list_link_clear(gs_list_link_t *llink)
+{
+ ((struct gs_list_link *)llink)->next = NULL;
+ ((struct gs_list_link *)llink)->prev = NULL;
+}
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal gs_list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __gs_list_add(struct gs_list_link * new,
+ struct gs_list_link * prev,
+ struct gs_list_link * next)
+{
+ next->prev = new;
+ new->next = next;
+ new->prev = prev;
+ prev->next = new;
+}
+
+/**
+ * gs_list_add - add a new entry
+ * @new: new entry to be added
+ * @head: gs_list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static inline void gs_list_add(struct gs_list_link *new, gs_list_t *head)
+{
+ __gs_list_add(new, head, head->next);
+}
+
+/**
+ * gs_list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: gs_list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static inline void gs_list_add_tail(struct gs_list_link *new, gs_list_t *head)
+{
+ __gs_list_add(new, head->prev, head);
+}
+
+/*
+ * Delete a gs_list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal gs_list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __gs_list_del(struct gs_list_link * prev,
+ struct gs_list_link * next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+/**
+ * gs_list_del - deletes entry from gs_list.
+ * @entry: the element to delete from the gs_list.
+ * Note: gs_list_empty on entry does not return true after this, the entry is in an undefined state.
+ */
+static inline void gs_list_del(struct gs_list_link *entry)
+{
+ assert(entry->prev != NULL && entry->next != NULL);
+ __gs_list_del(entry->prev, entry->next);
+ entry->prev = NULL; entry->next = NULL;
+}
+
+/**
+ * gs_list_del_clear - deletes entry from gs_list and reinitialize it.
+ * @entry: the element to delete from the gs_list.
+ */
+static inline void gs_list_del_clear(struct gs_list_link *entry)
+{
+ __gs_list_del(entry->prev, entry->next);
+ gs_list_link_clear(entry);
+}
+
+/**
+ * gs_list_empty - tests whether a gs_list is empty
+ * @head: the gs_list to test.
+ */
+static inline int gs_list_empty(gs_list_t *head)
+{
+ return head->next == head;
+}
+
+/**
+ * gs_list_splice - join two gs_lists
+ * @gs_list: the new gs_list to add.
+ * @head: the place to add it in the first gs_list.
+ */
+static inline void gs_list_splice(gs_list_t *gs_list, struct gs_list_link *llink)
+{
+ struct gs_list_link *first = gs_list->next;
+
+ if (first != gs_list) {
+ struct gs_list_link *last = gs_list->prev;
+ struct gs_list_link *at = llink->next;
+
+ first->prev = llink;
+ llink->next = first;
+
+ last->next = at;
+ at->prev = last;
+ }
+}
+
+/**
+ * gs_list_get_entry - get the struct for this entry
+ * @ptr: the &struct gs_list_link pointer.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the gs_list_struct within the struct.
+ */
+#define gs_list_get_entry(ptr, type, member) \
+ ((ptr != NULL) ? ((type *)((char *)(ptr)-(unsigned long)((&((type *)0)->member)))) : NULL)
+
+/**
+ * gs_list_for_each - iterate over a list safe against removal of list entry
+ * @pos: the struct gs_list_link * to use as a loop counter.
+ */
+#define gs_list_for_each(pos, head) \
+ for (struct gs_list_link *scratch = ((struct gs_list_link *)head)->next, \
+ pos = ((struct gs_list_link *)head)->next; \
+ pos != ((struct gs_list_link *)head); \
+ pos = scratch, scratch = pos->next)
+
+/**
+ * gs_list_for_each_entry -
+ * iterate over list of given type safe against removal of list entry
+ * @pos: the type * to use as a loop counter.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define gs_list_for_each_entry(pos, head, member) \
+ for (struct gs_list_link *scratch = (head)->next, \
+ pos = gs_list_get_entry((head)->next, typeof(*pos), member); \
+ pos && (&pos->member != (head)); \
+ pos = gs_list_get_entry(scratch, typeof(*pos), member), \
+ scratch = pos->member.next)
+
+static inline int gs_list_exists(gs_list_t *list, struct gs_list_link *llink)
+{
+ struct gs_list_link *mypos;
+ gs_list_for_each(mypos, list)
+ {
+ if(mypos == llink)
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static inline struct gs_list_link * gs_list_find(
+ gs_list_t *list,
+ int (*compare)(struct gs_list_link *, void *),
+ void *ptr)
+{
+ struct gs_list_link *pos;
+ gs_list_for_each(pos, list)
+ {
+ if(compare(pos, ptr))
+ {
+ return pos;
+ }
+ }
+ return NULL;
+}
+
+#define gs_list_push(__list, __entry) gs_list_add_tail((__entry), (__list))
+
+static inline struct gs_list_link * gs_list_pop(gs_list_t *list)
+{
+ struct gs_list_link *entry = list->next;
+ if(gs_list_empty(list)) return NULL;
+ gs_list_del(list->next);
+ return entry;
+}
+
+static inline struct gs_list_link *gs_list_peek(gs_list_t *list)
+{
+ if(list->next == list) return NULL;
+ return list->next;
+}
+
+#endif
+
+/*
+ * Local variables:
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * End:
+ *
+ * vim: ts=8 sts=4 sw=4 expandtab
+ */
diff --git a/code/src/gsl/common/gs-node.h b/code/src/gsl/common/gs-node.h
new file mode 100644
index 0000000..7d3193d
--- /dev/null
+++ b/code/src/gsl/common/gs-node.h
@@ -0,0 +1,15 @@
+#ifndef __GS_NODE_H__
+#define __GS_NODE_H__
+
+#include "common/gs-types.h"
+
+/**
+ * The gs_node_t is an opaque address for a node in the system.
+ */
+typedef uint128_t gs_node_t;
+
+gs_node_t gs_mynode(void);
+
+void gs_set_mynode(gs_node_t node);
+
+#endif /* __GS_NODE_H__ */
diff --git a/code/src/gsl/common/gs-safe-list.h b/code/src/gsl/common/gs-safe-list.h
new file mode 100644
index 0000000..cfc6f1e
--- /dev/null
+++ b/code/src/gsl/common/gs-safe-list.h
@@ -0,0 +1,161 @@
+#ifndef __GS_SAFE_LIST_H__
+#define __GS_SAFE_LIST_H__
+
+#ifdef __STRICT_ANSI__
+/* strict ANSI C doesn't have 'inline' functions, so we use __inline__ instead */
+#define inline __inline__
+#endif
+
+#include "include/gs-count-list.h"
+
+typedef struct
+{
+ gs_countlist_t list;
+ gs_mutex_t mutex;
+} gs_safelist_t;
+
+typedef gs_countlist_link_t gs_safelist_link_t;
+
+#define GS_SAFE_LIST_STATIC_INITIALIZER(name) \
+ { { { &(name), &(name) }, 0 }, GS_MUTEX_INITIALIZER }
+
+#define GS_SAFE_LIST_DEFINE(name) \
+ gs_safelist_t name = GS_SAFE_LIST_STATIC_INITIALIZER(name)
+
+#define gs_safelist_link_clear(__link) do { \
+ gs_list_link_clear(&((__link)->link)); \
+} while(0)
+
+static inline void gs_safelist_init(gs_safelist_t *slist)
+{
+ gs_mutex_lock(&slist->mutex);
+ gs_countlist_init(&slist->list);
+ gs_mutex_unlock(&slist->mutex);
+}
+
+static inline void gs_safelist_add(
+ struct gs_safelist_link_t *new, gs_safelist_t *slist)
+{
+ gs_mutex_lock(&slist->mutex);
+ gs_countlist_add(&new->link, slist->list);
+ gs_mutex_unlock(&slist->mutex);
+}
+
+static inline void gs_safelist_add_tail(
+ gs_safelist_link_t *new, gs_safelist_t *slist)
+{
+ gs_mutex_lock(&slist->mutex);
+ gs_countlist_add_tail(&new->link, slist->list);
+ gs_mutex_unlock(&slist->mutex);
+}
+
+static inline void gs_safelist_del(
+ gs_safelist_link_t *entry, gs_safelist_t *clist)
+{
+ gs_mutex_lock(&slist->mutex);
+ gs_list_del(&entry->link);
+ gs_mutex_unlock(&slist->mutex);
+}
+
+static inline int gs_safelist_empty(gs_safelist_t *slist)
+{
+ int empty;
+ gs_mutex_lock(&slist->mutex);
+ empty = gs_countlist_empty(&slist->list);;
+ gs_mutex_unlock(&slist->mutex);
+ return empty;
+}
+
+#define gs_safelist_push(_op, _clist) gs_safelist_add_tail(_op, _clist)
+
+static inline gs_safelist_link_t *gs_safelist_pop(gs_safelist_t *list)
+{
+ struct gs_safelist_link *entry;
+ gs_mutex_lock(&slist->mutex);
+ entry = gs_countlist_pop(&list->list);
+ gs_mutex_unlock(&slist->mutex);
+ return entry;
+}
+
+static inline gs_safelist_link_t *gs_safelist_peek(gs_safelist_t *list)
+{
+ gs_safelist_link_t *entry;
+ gs_mutex_lock(&list->mutex);
+ entry = gs_countlist_peek(&list->list);
+ gs_mutex_unlock(&list->mutex);
+ return entry;
+}
+
+#define gs_safelist_get_entry(ptr, type, member) \
+ gs_countlist_get_entry(ptr, type, member)
+
+#define gs_safelist_link_from_countlist_link(_ptr) \
+ gs_countlist_get_entry(_ptr, gs_safelist_link_t, link)
+
+/* these are automatically safe */
+
+#define gs_safelist_for_each(pos, slist) \
+ for(gs_mutex_lock(&slist->mutex), \
+ struct gs_list_link *lpos = ((slist)->list).list.next, \
+ struct gs_list_link *scratch = lpos, \
+ pos = gs_list_get_entry(lpos, gs_countlist_link_t, link), \
+ gs_mutex_unlock(&slist->mutex); \
+ gs_mutex_lock(&slist->mutex) || lpos != &(slist->list).list || gs_mutex_unlock(&slist->mutex); \
+ gs_mutex_lock(&slist->mutex), \
+ lpos = scratch, \
+ scratch = lpos->next, \
+ pos = gs_list_get_entry(lpos, gs_countlist_link_t, link), \
+ gs_mutex_unlock(&slist->mutex))
+
+#define gs_safelist_for_each_entry(pos, slist, member) \
+ for (gs_mutex_lock(struct gs_list_link lpos = ((slist)->list).next, \
+ struct gs_list_link *scratch = lpos, \
+ pos = gs_countlist_get_entry( \
+ gs_list_get_entry(lpos, gs_safelist_link_t, link), \
+ typeof(*pos), member); \
+ lpos != &(slist)->list; \
+ lpos = scratch->next, scratch = lpos->next, \
+ pos = gs_countlist_get_entry( \
+ gs_list_get_entry(lpos, gs_countlist_link_t, link), \
+ typeof(*pos), member))
+
+static inline int gs_safelist_exists(gs_safelist_t *slist, gs_safelist_link_t *llink)
+{
+ gs_mutex_lock(&slist->mutex);
+ ret = gs_list_exists(&(slist->list.list), llink);
+ gs_mutex_unlock(&slist->mutex);
+ return ret;
+}
+
+static inline int
+#define gs_countlist_find(clist, compare, ptr) \
+ gs_countlist_find(&(clist->list), compare, ptr)
+
+#define gs_countlist_push(__list, __entry) gs_list_push(&(__list)->list, __entry)
+
+#define gs_countlist_pop(__list) gs_list_pop(&(__list)->list)
+
+#define gs_countlist_peek(__list) gs_list_peek(&(__list)->list)
+
+static inline uint64_t gs_countlist_count(gs_countlist_t *list)
+{
+ return list->count;
+}
+
+static inline gs_countlist_link_t *gs_countlist_find(
+ gs_countlist_t *list,
+ int (*compare)(struct gs_countlist_link_t *, void *),
+ void *ptr)
+{
+ struct gs_countlist_link_t *llink;
+ gs_countlist_for_each(llink, list)
+ {
+ if(compare(llink, list))
+ {
+ return llink;
+ }
+ }
+ return NULL;
+}
+
+#endif /* __GS_COUNT_LIST_H__ */
diff --git a/code/src/gsl/common/gs-types.h b/code/src/gsl/common/gs-types.h
new file mode 100644
index 0000000..10feadb
--- /dev/null
+++ b/code/src/gsl/common/gs-types.h
@@ -0,0 +1,17 @@
+#ifndef __GS_TYPES_H__
+#define __GS_TYPES_H__
+
+#include <stdint.h>
+
+typedef struct { uint64_t l; uint64_t u; } uint128_t;
+
+/**
+ * The gs_string_t is a null-terminated string. Used for encoding
+ * strings.
+ */
+typedef char * gs_string_t;
+
+#include "common/gs-buffer.h"
+#include "common/gs-error.h"
+
+#endif /* __GS_TYPES_H__ */
diff --git a/code/src/gsl/common/gs.h b/code/src/gsl/common/gs.h
new file mode 100644
index 0000000..f678142
--- /dev/null
+++ b/code/src/gsl/common/gs.h
@@ -0,0 +1,128 @@
+#ifndef __GS_H__
+#define __GS_H__
+
+#include <string.h>
+#include <stdint.h>
+#include <assert.h>
+
+#include "include/gs-list.h"
+
+#define GS_MAX_RESOURCES 255
+#define GS_MAX_CONTEXTS 1024
+
+#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>
+#endif
+
+typedef enum
+{
+ GS_POSTED = 0,
+ GS_COMPLETE = 1
+} gs_ret_t;
+
+typedef struct gs_hints *gs_hints_t;
+typedef struct gs_context *gs_context_t;
+
+typedef uint64_t gs_op_id_t;
+
+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__
+
+typedef pthread_mutex_t gs_mutex_t;
+typedef pthread_mutexattr_t gs_mutexattr_t;
+#define gs_mutex_lock(__mut) pthread_mutex_lock(__mut)
+#define gs_mutex_unlock(__mut) pthread_mutex_unlock(__mut)
+#define gs_mutex_init(__mut, __attr) pthread_mutex_init(__mut, __attr)
+#define GS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
+#define GS_COND_INITIALIZER PTHREAD_COND_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;
+typedef int gs_mutexattr_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 inline int gs_mutex_init(gs_mutex_t *__mut, gs_mutexattr_t *__attr) {return 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
+
+/* The resource structure is defined by a given resource, and registered
+ * to the gs management code during resource initialization.
+ */
+struct gs_resource
+{
+ const 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_context_t ctx, gs_op_id_t id);
+ int (*register_context)(gs_context_t context);
+ int (*unregister_context)(gs_context_t context);
+};
+
+/* 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);
+
+/* 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, ...);
+
+/* Context destruction. Called to cleanup state allocated in gs_context_create.
+ */
+int gs_context_destroy(gs_context_t context);
+
+/* Poll for completion of the operations within the given context up to a
+ * timeout value.
+ */
+int gs_poll(gs_context_t context, int ms);
+
+/* Cancel an operation */
+int gs_cancel_op(gs_context_t context, gs_op_id_t op_id);
+
+#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)
+
+#include "gs-internal.h"
+
+#endif
diff --git a/code/src/gsl/include/gs.h b/code/src/gsl/include/gs.h
deleted file mode 100644
index 338fa18..0000000
--- a/code/src/gsl/include/gs.h
+++ /dev/null
@@ -1,131 +0,0 @@
-#ifndef __GS_H__
-#define __GS_H__
-
-#include <string.h>
-#include <stdint.h>
-#include <assert.h>
-
-#include "include/gs-list.h"
-
-#define GS_ERR_MASK (1 << 7)
-#define GS_ECANCELLED (GS_ERR_MASK | 1)
-
-#define GS_MAX_RESOURCES 255
-#define GS_MAX_CONTEXTS 1024
-
-#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>
-#endif
-
-typedef enum
-{
- GS_POSTED = 0,
- GS_COMPLETE = 1
-} gs_ret_t;
-
-typedef struct gs_hints *gs_hints_t;
-typedef struct gs_context *gs_context_t;
-
-typedef uint64_t gs_op_id_t;
-
-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__
-
-typedef pthread_mutex_t gs_mutex_t;
-typedef pthread_mutexattr_t gs_mutexattr_t;
-#define gs_mutex_lock(__mut) pthread_mutex_lock(__mut)
-#define gs_mutex_unlock(__mut) pthread_mutex_unlock(__mut)
-#define gs_mutex_init(__mut, __attr) pthread_mutex_init(__mut, __attr)
-#define GS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
-#define GS_COND_INITIALIZER PTHREAD_COND_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;
-typedef int gs_mutexattr_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 inline int gs_mutex_init(gs_mutex_t *__mut, gs_mutexattr_t *__attr) {return 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
-
-/* The resource structure is defined by a given resource, and registered
- * to the gs management code during resource initialization.
- */
-struct gs_resource
-{
- const 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_context_t ctx, gs_op_id_t id);
- int (*register_context)(gs_context_t context);
- int (*unregister_context)(gs_context_t context);
-};
-
-/* 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);
-
-/* 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, ...);
-
-/* Context destruction. Called to cleanup state allocated in gs_context_create.
- */
-int gs_context_destroy(gs_context_t context);
-
-/* Poll for completion of the operations within the given context up to a
- * timeout value.
- */
-int gs_poll(gs_context_t context, int ms);
-
-/* Cancel an operation */
-int gs_cancel_op(gs_context_t context, gs_op_id_t op_id);
-
-#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)
-
-#include "gs-internal.h"
-
-#endif
diff --git a/code/src/gsl/parser/CGen.lhs b/code/src/gsl/parser/CGen.lhs
index 0c33963..53f52ed 100644
--- a/code/src/gsl/parser/CGen.lhs
+++ b/code/src/gsl/parser/CGen.lhs
@@ -346,6 +346,10 @@ ctl->params.blah
> (newIdent p1name ni) True ni)
> (newIdent p2name ni) False ni) name False ni
+> addStructPtrPrefixPrefix :: String -> String -> String -> CExpr -> CExpr
+> addStructPtrPrefixPrefix sname p1name p2name (CVar name ni) =
+> CMember (CMember (CMember (CVar (newIdent sname ni) ni) (newIdent p1name ni) True ni) (newIdent p2name ni) True ni) name False ni
+
Take an assign statement, and insert a struct pointer prefix to the lhs. For example:
addStructToAssign "params" "mymem" "funcall(a, 123)"
diff --git a/code/src/gsl/parser/gs-blocking-parser.lhs b/code/src/gsl/parser/gs-blocking-parser.lhs
index 166a9e3..3dcec71 100644
--- a/code/src/gsl/parser/gs-blocking-parser.lhs
+++ b/code/src/gsl/parser/gs-blocking-parser.lhs
@@ -653,6 +653,15 @@ Each callback function defined for a given blocking function must have a unique
> addParams2Prefixes ctlPrefix p1Prefix p2Prefix idents stmt =
> everywhere (mkT $ addParams2PrefixToExpr ctlPrefix p1Prefix p2Prefix idents) stmt
+> addParams2PtrPrefixToExpr :: String -> String -> String -> [Ident] -> CExpr -> CExpr
+> addParams2PtrPrefixToExpr ctlPrefix p1Prefix p2Prefix locals expr
+> | isVarIn locals expr = addStructPtrPrefixPrefix ctlPrefix p1Prefix p2Prefix expr
+> | otherwise = expr
+
+> addParams2PtrPrefixes :: String -> String -> String -> [Ident] -> CStat -> CStat
+> addParams2PtrPrefixes ctlPrefix p1Prefix p2Prefix idents stmts =
+> everywhere (mkT $ addParams2PtrPrefixToExpr ctlPrefix p1Prefix p2Prefix idents) stmts
+
trLocals finds the local declarations for a blocking function context, and translates
the variables used in the statement, into variables prefixed with the ctl and parameter structures.
So for example, if a, b, c and d are local parameters, the statement:
@@ -669,10 +678,10 @@ runfun(ctl->fields.a, ctl->fields.b, ctl->fields.c, ctl->fields.d);
> let pbranchCtx = getPBranchAncestor bctx
> pwaitCtx = getPWaitAncestor bctx
> locals = join $ map getCDeclNames $ getPBranchDecls pbranchCtx
-> in (addParams2Prefixes ctlPrefix
-> (mkPWaitName (getPWaitId pwaitCtx))
-> (mkParamPBranchName (getPBranchId pbranchCtx))
-> locals) stmt
+> in (addParams2PtrPrefixes ctlPrefix
+> ((mkPWaitName (getPWaitId pwaitCtx)) ++ "." ++ mkSharedPtrName)
+> (mkParamPBranchName (getPBranchId pbranchCtx))
+> locals) stmt
> | otherwise = stmt
> trPWaitLocals :: String -> BlockingContext -> CStat -> CStat
diff --git a/code/src/gsl/parser/gs-remote-parser.lhs b/code/src/gsl/parser/gs-remote-parser.lhs
index 9c4c991..afa3053 100644
--- a/code/src/gsl/parser/gs-remote-parser.lhs
+++ b/code/src/gsl/parser/gs-remote-parser.lhs
@@ -73,7 +73,7 @@ CTypeOfType CDecl NodeInfo
> mkEncodeBlock :: NodeInfo -> Bool -> String -> String -> [CStat]
> mkEncodeBlock ni isPtr typeName fieldName = mkStmtsFromCLines ni $
> "{ \
-> \ ret = gs_encode_"++typeName++"(buf, "++fieldName++", "++(if isPtr then "" else "&")++"x->"++fieldName++"); \
+> \ ret = gs_encode_"++typeName++"(buf, \""++fieldName++"\", "++(if isPtr then "" else "&")++"x->"++fieldName++"); \
> \ if(ret != 0) \
> \ { \
> \ return ret; \
@@ -103,7 +103,7 @@ CTypeOfType CDecl NodeInfo
> mkDecodeBlock :: NodeInfo -> Bool -> String -> String -> [CStat]
> mkDecodeBlock ni isPtr typeName fieldName = mkStmtsFromCLines ni $
> "{ \
-> \ ret = gs_decode_"++typeName++"(buf, "++fieldName++", "++(if isPtr then "" else "&")++"x->"++fieldName++"); \
+> \ ret = gs_decode_"++typeName++"(buf, \""++fieldName++"\", "++(if isPtr then "" else "&")++"x->"++fieldName++"); \
> \ if(ret != 0) \
> \ { \
> \ return ret; \
@@ -133,7 +133,7 @@ CTypeOfType CDecl NodeInfo
> mkSizeBlock :: NodeInfo -> Bool -> String -> String -> [CStat]
> mkSizeBlock ni isPtr typeName fieldName = mkStmtsFromCLines ni $
> "{ \
-> \ size += gs_encode_size_"++typeName++"("++fieldName++", "++(if isPtr then "" else "&")++"x->"++fieldName++"); \
+> \ size += gs_encode_size_"++typeName++"(\""++fieldName++"\", "++(if isPtr then "" else "&")++"x->"++fieldName++"); \
> \}"
> mkSizeStmts :: [CDecl] -> NodeInfo -> RemoteT CStat
@@ -412,7 +412,7 @@ CTypeOfType CDecl NodeInfo
> \ { \
> \ return ret; \
> \ } \
-> \ ret = "++fname++"("++inName++", &"++outName++"); \
+> \ ret = "++fname++"(\""++inName++"\", &"++outName++"); \
> \ if(ret != GS_SUCCESS) \
> \ { \
> \ return ret; \
diff --git a/code/src/gsl/proto/gs-byteswap.h b/code/src/gsl/proto/gs-byteswap.h
new file mode 100644
index 0000000..4d6e9fc
--- /dev/null
+++ b/code/src/gsl/proto/gs-byteswap.h
@@ -0,0 +1,112 @@
+/* Macros to swap the order of bytes in integer values.
+ Copyright (C) 1997, 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* Modified by Phil Carns ([email protected])
+ * June 2003
+ * For use with custom network encoding routines in the BMI component of
+ * the Parallel Virtual File System version 2.
+ */
+
+#ifndef __GS_BYTESWAP_H
+#define __GS_BYTESWAP_H
+
+#include "gs-config.h"
+
+#ifndef __bswap_16
+/* Swap bytes in 16 bit value. */
+#ifdef __GNUC__
+# define __bswap_16(x) \
+ (__extension__ \
+ ({ unsigned short int __bsx = (x); \
+ ((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8)); }))
+#else
+static __inline unsigned short int
+__bswap_16 (unsigned short int __bsx)
+{
+ return ((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8));
+}
+#endif
+#endif
+
+#ifndef __bswap_32
+/* Swap bytes in 32 bit value. */
+#ifdef __GNUC__
+# define __bswap_32(x) \
+ (__extension__ \
+ ({ unsigned int __bsx = (x); \
+ ((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >> 8) | \
+ (((__bsx) & 0x0000ff00) << 8) | (((__bsx) & 0x000000ff) << 24)); }))
+#else
+static __inline unsigned int
+__bswap_32 (unsigned int __bsx)
+{
+ return ((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >> 8) |
+ (((__bsx) & 0x0000ff00) << 8) | (((__bsx) & 0x000000ff) << 24));
+}
+#endif
+#endif
+
+#ifndef __bswap_64
+#if defined __GNUC__ && __GNUC__ >= 2
+/* Swap bytes in 64 bit value. */
+# define __bswap_constant_64(x) \
+ ((((x) & 0xff00000000000000ull) >> 56) \
+ | (((x) & 0x00ff000000000000ull) >> 40) \
+ | (((x) & 0x0000ff0000000000ull) >> 24) \
+ | (((x) & 0x000000ff00000000ull) >> 8) \
+ | (((x) & 0x00000000ff000000ull) << 8) \
+ | (((x) & 0x0000000000ff0000ull) << 24) \
+ | (((x) & 0x000000000000ff00ull) << 40) \
+ | (((x) & 0x00000000000000ffull) << 56))
+
+# define __bswap_64(x) \
+ (__extension__ \
+ ({ union { __extension__ unsigned long long int __ll; \
+ unsigned int __l[2]; } __w, __r; \
+ if (__builtin_constant_p (x)) \
+ __r.__ll = __bswap_constant_64 (x); \
+ else \
+ { \
+ __w.__ll = (x); \
+ __r.__l[0] = __bswap_32 (__w.__l[1]); \
+ __r.__l[1] = __bswap_32 (__w.__l[0]); \
+ } \
+ __r.__ll; }))
+#else
+#ifdef WORDS_BIGENDIAN
+#error FIX ME: no 64 bit bswap routine for non GNUC preprocessor.
+#endif
+#endif
+#endif
+
+#ifdef WORDS_BIGENDIAN
+#define gshton16(x) __bswap_16(x)
+#define gshton32(x) __bswap_32(x)
+#define gshton64(x) __bswap_64(x)
+#else
+#define gshton16(x) x
+#define gshton32(x) x
+#define gshton64(x) x
+#endif
+
+#define gsntoh16(x) gshton16(x)
+#define gsntoh32(x) gshton32(x)
+#define gsntoh64(x) gshton64(x)
+
+#endif /* __BMI_BYTESWAP_H */
diff --git a/code/src/gsl/proto/gs-encoding-pw.h b/code/src/gsl/proto/gs-encoding-pw.h
new file mode 100644
index 0000000..c0f9b02
--- /dev/null
+++ b/code/src/gsl/proto/gs-encoding-pw.h
@@ -0,0 +1,442 @@
+#ifndef __GS_ENCODING_PW_H__
+#define __GS_ENCODING_PW_H__
+
+/*
+ * This is an efficient encoding scheme based on Pete Wyckoff's encoding
+ * scheme in PVFS. PW's scheme used CPP macros, whereas this one uses
+ * inlined functions in order to avoid the headache and hassle that comes
+ * with CPP macros (no type checking, can't be debugged properly, etc.), but
+ * still gain the performance of inlined code.
+ *
+ * The encoding scheme rely's on byte swapping everything to little endian
+ * in its encoded form. This means little endian machines need to do nothing
+ * besides copy data directly to the structure. See gs-byteswap.h.
+ *
+ * This encoding scheme is used by the GS remote generation code, and is expected
+ * to have a specific format and set of encoding/decoding functions for each basic
+ * type. The required functions and format are:
+ *
+ * gs_ret_t gs_encode_<typename>(
+ * gs_buffer_t *buf, const gs_string_t varname, <typename> *x);
+ *
+ * gs_ret_t gs_decode_<typename>(
+ * gs_buffer_t *buf, gs_string_t *varname, <typename> *x);
+ *
+ * uint64_t gs_encode_size_<typename>(const gs_string_t varname, <typename> *x);
+ *
+ * The varname fields are included in the function signature for other
+ * schemes, this scheme does not include variable names (its not self-describing)
+ * in its encoding format.
+ *
+ * Encoding/decoding macros are required for list types, because
+ * we need to be able to invoke specific encoding routines for
+ * each element of the list without using function pointers.
+ * their signatures are slightly different:
+ *
+ * void gs_encode_<typename>(
+ * gs_buffer_t *buf,
+ * const gs_string_t varname,
+ * <typename> *cx,
+ * <element typename>,
+ * <element varname>,
+ * <element typename>,
+ * gs_ret_t *ret);
+ *
+ * void gs_decode_<typename>(
+ * gs_buffer_t *buf,
+ * const gs_string_t varname,
+ * <typename> *cx,
+ * <element typename>,
+ * <element varname>,
+ * gs_ret_t *ret);
+ *
+ * gs_ret_t gs_encode_size_<typename>(
+ * <typename> *cx,
+ * const gs_string_t varname,
+ * <element typename>,
+ * uint64_t *size);
+ *
+ * see the GS remote documentation for further info.
+ */
+
+#include <assert.h>
+
+#include "common/gs-types.h"
+#include "common/gs-buffer.h"
+#include "proto/gs-byteswap.h"
+
+/* macros used by pw encoding macros - probably shouldn't
+ * be used elsewhere
+ */
+#define gs_roundup4(x) (((x)+3) & ~3)
+#define gs_roundup8(x) (((x)+7) & ~7)
+
+/* basic encoding types */
+
+/* Type: uint128_t
+ *
+ * 16 byte unsigned integer. This is an additional type not included
+ * in stdint.h. We use it for unique ids (nodes, objects), so we
+ * provide encoding/decoding functions here.
+ *
+ * Format: [VALUE]
+ * Bytes: <16>
+ */
+static inline uint64_t gs_encode_size_uint128_t(
+ const gs_string_t n __unused, uint128_t *x)
+{
+ return sizeof(uint128_t);
+}
+static inline gs_ret_t gs_encode_uint128_t(
+ gs_buffer_t *buf, const gs_string_t n __unused, uint128_t *x)
+{
+ assert(buf);
+ assert(x);
+ gs_buffer_check_overflow(buf, 16);
+ *(uint64_t *) (gs_buffer_cptr(buf)) = gshton64((x)->l);
+ gs_buffer_inc(buf, 8);
+ *(uint64_t *) (gs_buffer_cptr(buf)) = gshton64((x)->u);
+ gs_buffer_inc(buf, 8);
+ return GS_SUCCESS;
+}
+static inline gs_ret_t gs_decode_uint128_t(
+ gs_buffer_t *buf, const gs_string_t n __unused, uint128_t *x)
+{
+ assert(buf);
+ assert(x);
+ gs_buffer_check_overflow(buf, 16);
+ (x)->l = gsntoh64(*(uint64_t *)(gs_buffer_cptr(buf)));
+ gs_buffer_inc(buf, 8);
+ (x)->u = gsntoh64(*(uint64_t *)(gs_buffer_cptr(buf)));
+ gs_buffer_inc(buf, 8);
+ return GS_SUCCESS;
+}
+
+/* Type: uint64_t
+ *
+ * 8 byte unsigned integer
+ *
+ * Format: [VALUE]
+ * Bytes: <8>
+ */
+static inline uint64_t gs_encode_size_uint64_t(
+ const gs_string_t n __unused, uint64_t *x)
+{
+ return sizeof(uint64_t);
+}
+static inline gs_ret_t gs_encode_uint64_t(
+ gs_buffer_t *buf, const gs_string_t n __unused, uint64_t *x)
+{
+ assert(buf);
+ assert(x);
+ gs_buffer_check_overflow(buf, 8);
+ *(uint64_t *) (gs_buffer_cptr(buf)) = gshton64(*(x));
+ gs_buffer_inc(buf, 8);
+ return GS_SUCCESS;
+}
+static inline gs_ret_t gs_decode_uint64_t(
+ gs_buffer_t *buf, gs_string_t *n __unused, uint64_t *x)
+{
+ assert(buf);
+ assert(x);
+ gs_buffer_check_overflow(buf, 8);
+ *(x) = gsntoh64(*(uint64_t*) (gs_buffer_cptr(buf)));
+ gs_buffer_inc(buf, 8);
+ return GS_SUCCESS;
+}
+
+/* Type: int64_t
+ *
+ * 8 byte signed integer
+ *
+ * Format: [VALUE]
+ * Bytes: <8>
+ */
+static inline uint64_t gs_encode_size_int64_t(
+ const gs_string_t n __unused, int64_t *x)
+{
+ return sizeof(int64_t);
+}
+static inline gs_ret_t gs_encode_int64_t(
+ gs_buffer_t *buf, const gs_string_t n __unused, int64_t *x)
+{
+ assert(buf);
+ assert(x);
+ gs_buffer_check_overflow(buf, 8);
+ *(int64_t*) (gs_buffer_cptr(buf)) = gshton64(*(x));
+ gs_buffer_inc(buf, 8);
+}
+static inline gs_ret_t gs_decode_int64_t(
+ gs_buffer_t *buf, gs_string_t *n __unused, int64_t *x)
+{
+ assert(buf);
+ assert(x);
+ gs_buffer_check_overflow(buf, 8);
+ *(x) = gsntoh64(*(int64_t*) (gs_buffer_cptr(buf)));
+ gs_buffer_inc(buf, 8);
+}
+
+/* Type: uint32_t
+ *
+ * 4 byte unsigned integer
+ *
+ * Format: [VALUE]
+ * Bytes: <4><4 byte padding>
+ */
+static inline uint64_t gs_encode_size_uint32_t(
+ const gs_string_t n __unused, uint32_t *x)
+{
+ return sizeof(uint32_t);
+}
+static inline gs_ret_t gs_encode_uint32_t(
+ gs_buffer_t *buf, const gs_string_t n __unused, uint32_t *x)
+{
+ assert(buf);
+ assert(x);
+ gs_buffer_check_overflow(buf, 8);
+ *(uint32_t*) *(gs_buffer_cptr(buf)) = gshton32(*(x));
+ gs_buffer_inc(buf, 8);
+}
+static inline gs_ret_t gs_decode_uint32_t(
+ gs_buffer_t *buf, gs_string_t *n __unused, uint32_t *x)
+{
+ assert(buf);
+ assert(x);
+ gs_buffer_check_overflow(buf, 8);
+ *(x) = gsntoh32(*(uint32_t*) (gs_buffer_cptr(buf)));
+ gs_buffer_inc(buf, 8);
+}
+
+/* Type: int32_t
+ *
+ * 4 byte signed integer
+ *
+ * Format: [VALUE]
+ * Bytes: <4>
+ */
+static inline uint64_t gs_encode_size_int32_t(
+ const gs_string_t n __unused, int32_t *x)
+{
+ return sizeof(int32_t);
+}
+static inline gs_ret_t gs_encode_int32_t(
+ gs_buffer_t *buf, const gs_string_t n __unused, int32_t *x)
+{
+ assert(buf);
+ assert(x);
+ gs_buffer_check_overflow(buf, 8);
+ *(int32_t*) (gs_buffer_cptr(buf)) = gshton32(*(x));
+ gs_buffer_inc(buf, 8);
+}
+static inline gs_ret_t gs_decode_int32_t(
+ gs_buffer_t *buf, gs_string_t *n __unused, int32_t *x)
+{
+ assert(buf);
+ assert(x);
+ gs_buffer_check_overflow(buf, 8);
+ *(x) = gsntoh32(*(int32_t*) *(gs_buffer_cptr(buf)));
+ gs_buffer_inc(buf, 4);
+}
+
+/* Type: gs_string_t
+ *
+ * This is a null terminated ASCII string.
+ *
+ * Format: [LENGTH][STRING][PAD8]
+ * Bytes: <4><LENGTH+1><PAD8>
+ *
+ * Padding is added to the end of the encoded string to make the entire encoding
+ * 8-byte aligned. If the string is null or null terminator is the only character,
+ * the format changes to [0][0], with a total size of 8.
+ */
+static inline uint64_t gs_encode_size_gs_string_t(
+ const gs_string_t n __unused, gs_string_t *x)
+{
+ uint32_t len = 0;
+ if(*x)
+ {
+ len = strlen(*x);
+ return gs_roundup8(4 + len + 1);
+ }
+ else
+ {
+ return 8;
+ }
+}
+static inline gs_ret_t gs_encode_gs_string_t(
+ gs_buffer_t *buf, const gs_string_t n __unused , gs_string_t *x)
+{
+ assert(buf);
+ assert(x);
+ uint32_t len = 0;
+ if (*x) len = strlen(*x);
+ *(uint32_t *) (gs_buffer_cptr(buf)) = gshton32(len);
+ if (len)
+ {
+ memcpy((gs_buffer_cptr(buf)+4), *x, len+1);
+ gs_buffer_inc(buf, gs_roundup8(4 + len + 1));
+ }
+ else
+ {
+ *(uint32_t *) (gs_buffer_cptr(buf)+4) = 0;
+ gs_buffer_inc(buf, 8);
+ }
+ return GS_SUCCESS;
+}
+static inline gs_ret_t gs_decode_gs_string_t(
+ gs_buffer_t *buf, gs_string_t *n __unused, gs_string_t *x)
+{
+ assert(buf);
+ assert(x);
+ uint32_t len = gsntoh32(*(uint32_t *) (gs_buffer_cptr(buf)));
+ *x = (gs_buffer_cptr(buf)+4);
+ if (len)
+ {
+ gs_buffer_inc(buf, roundup8(4 + len + 1));
+ }
+ else
+ {
+ gs_buffer_inc(buf, 8);
+ }
+ return GS_SUCCESS;
+}
+
+/**
+ * Type: gs_buffer_t
+ *
+ * The generic buffer type. An array of bytes and a size.
+ * Format: [SIZE][BUFFER]...[PAD8]
+ */
+static inline uint64_t gs_encode_size_gs_buffer_t(
+ const gs_string_t n __unused, gs_buffer_t *x)
+{
+ assert(x);
+ if(x->buffer)
+ {
+ return gs_roundup8(8 + x->size);
+ }
+ return size;
+}
+
+static inline gs_ret_t gs_encode_gs_buffer_t(
+ gs_buffer_t *buffer, gs_string_t n __unused, gs_buffer_t *x)
+{
+ gs_ret_t ret;
+
+ assert(buffer);
+ assert(x);
+ gs_buffer_check_overflow(buffer, gs_roundup8(8 + x->size));
+ ret = gs_encode_uint64_t(buffer, "size", &x->size);
+ if(ret != GS_SUCCESS)
+ {
+ return ret;
+ }
+
+ memcpy(gs_buffer_cpr(buffer), x->buffer, x->size);
+ gs_buffer_inc(gs_roundup8(x->size));
+ return 0;
+}
+
+static inline gs_ret_t gs_decode_gs_buffer_t(
+ gs_buffer_t *buffer, gs_string_t n __unused, gs_buffer_t *x)
+{
+ gs_ret_t ret;
+ uint64_t size;
+
+ assert(buffer);
+ assert(x);
+
+ ret = gs_decode_uint64_t(buffer, &size);
+ if(ret != GS_SUCCESS)
+ {
+ return ret;
+ }
+ gs_buffer_check_overflow(buffer, gs_roundup8(x->size));
+ ret = gs_buffer_alloc(x, size);
+ if(ret != GS_SUCCESS)
+ {
+ return ret;
+ }
+ memcpy(x->buffer, buffer, x->size);
+ gs_buffer_inc(buffer, gs_roundup8(x->size));
+ return GS_SUCCESS;
+}
+
+/**
+ * Type: gs_error_t
+ *
+ * The error type. We encode the error An array of bytes and a size.
+ * Format: [SIZE][BUFFER]...[PAD8]
+ */
+static inline uint64_t gs_encode_size_gs_error_t(
+ const gs_string_t n __unused, gs_buffer_t *x)
+{
+ assert(x);
+ if(x->buffer)
+ {
+ return gs_roundup8(8 + x->size);
+ }
+ return size;
+}
+
+/* Type: gs_countlist_t
+ *
+ * A list of typed structures. Note the gs_list_t type does not keep
+ * track of its size, and so only provide encoding functions for the
+ * gs_countlist_t type. That should be used where a list is expected to
+ * be serialized.
+ *
+ * Format: [COUNT][ELEM1][ELEM2]...[PAD8]
+ * Bytes: <4>
+ *
+ * Note the size function (macro) is expensive, as we have to calculate the
+ * sizes of individual elements. The remote code should avoid using it.
+ */
+#define gs_encode_size_gs_countlist_t(__list, __varname, __typename, __size) do { \
+ __typename *__pos; \
+ __sum = 0; \
+ gs_countlist_for_each_entry(__pos, __list) \
+ { \
+ __sum += gs_encode_size_##__typename(__pos, NULL); \
+ } \
+ *(__size) = gs_roundup8(8 + __sum); \
+} while(0)
+
+#define gs_encode_gs_countlist_t( \
+ __buf, __varname, __list, __typename, __member, __ret) do { \
+ __typename *__pos; \
+ gs_ret_t mret; \
+ mret = gs_encode_uint64_t(__buf, NULL, gs_countlist_count(__list)); \
+ if(mret == GS_SUCCESS) \
+ { \
+ gs_countlist_for_each_entry(__pos, __list, __member) \
+ { \
+ mret = gs_encode_##__typename(__buf, NULL, __pos); \
+ if(mret != GS_SUCCESS) break; \
+ } \
+ } \
+ *(__ret) = mret; \
+} while(0)
+
+#define gs_decode_gs_countlist_t( \
+ __buf, __varname, __list, __typename, __member, __ret) do { \
+ __typename *__newt; \
+ uint64_t i = 0, uint64_t c; \
+ gs_ret_t mret; \
+ gs_countlist_init(__list); \
+ mret = gs_decode_uint64_t(__buf, NULL, &c); \
+ if(mret == GS_SUCCESS) \
+ { \
+ for(; i < c; ++i) \
+ { \
+ __newt = (__typename *)__buf; \
+ mret = gs_decode_##__typename(__buf, NULL, __newt); \
+ if(mret != GS_SUCCESS) break; \
+ gs_countlist_link_clear(&(__newt)->__member); \
+ gs_countlist_add_tail(&(__newt)->__member, __list); \
+ } \
+ } \
+ *(__ret) = mret; \
+} while(0)
+
+#endif /* __GS_ENCODING_PW_H__ */
diff --git a/code/src/gsl/proto/gs-encoding.h b/code/src/gsl/proto/gs-encoding.h
new file mode 100644
index 0000000..e96af66
--- /dev/null
+++ b/code/src/gsl/proto/gs-encoding.h
@@ -0,0 +1,7 @@
+#ifndef __GS_ENCODING_H__
+#define __GS_ENCODING_H__
+
+/* right now we use the PW encoding scheme */
+#include "proto/gs-encoding-pw.h"
+
+#endif
hooks/post-receive
--
Grayskull Repository
6092
Age (days ago)
6092
Last active (days ago)
0 comments
1 participants
participants (1)
-
noreply@mcs.anl.gov