http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f88168c2/net/oic/src/util/oc_etimer.h ---------------------------------------------------------------------- diff --git a/net/oic/src/util/oc_etimer.h b/net/oic/src/util/oc_etimer.h new file mode 100644 index 0000000..703b557 --- /dev/null +++ b/net/oic/src/util/oc_etimer.h @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels <a...@sics.se> + * + */ + +/** + * \defgroup etimer Event timers + * + * Event timers provides a way to generate timed events. An event + * timer will post an event to the process that set the timer when the + * event timer expires. + * + * An event timer is declared as a \c struct \c etimer and all access + * to the event timer is made by a pointer to the declared event + * timer. + * + * \sa \ref timer "Simple timer library" + * \sa \ref clock "Clock library" (used by the timer library) + * + * @{ + */ + +#ifndef OC_ETIMER_H +#define OC_ETIMER_H + +#include "oc_process.h" +#include "oc_timer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * A timer. + * + * This structure is used for declaring a timer. The timer must be set + * with oc_etimer_set() before it can be used. + * + * \hideinitializer + */ +struct oc_etimer +{ + struct oc_timer timer; + struct oc_etimer *next; + struct oc_process *p; +}; + +/** + * \name Functions called from application programs + * @{ + */ + +/** + * \brief Set an event timer. + * \param et A pointer to the event timer + * \param interval The interval before the timer expires. + * + * This function is used to set an event timer for a time + * sometime in the future. When the event timer expires, + * the event PROCESS_EVENT_TIMER will be posted to the + * process that called the oc_etimer_set() function. + * + */ +void oc_etimer_set(struct oc_etimer *et, oc_clock_time_t interval); + +/** + * \brief Reset an event timer with the same interval as was + * previously set. + * \param et A pointer to the event timer. + * + * This function resets the event timer with the same + * interval that was given to the event timer with the + * oc_etimer_set() function. The start point of the interval + * is the exact time that the event timer last + * expired. Therefore, this function will cause the timer + * to be stable over time, unlike the oc_etimer_restart() + * function. + * + * \sa oc_etimer_restart() + */ +void oc_etimer_reset(struct oc_etimer *et); + +/** + * \brief Reset an event timer with a new interval. + * \param et A pointer to the event timer. + * \param interval The interval before the timer expires. + * + * This function very similar to oc_etimer_reset. Opposed to + * oc_etimer_reset it is possible to change the timout. + * This allows accurate, non-periodic timers without drift. + * + * \sa oc_etimer_reset() + */ +void oc_etimer_reset_with_new_interval(struct oc_etimer *et, + oc_clock_time_t interval); + +/** + * \brief Restart an event timer from the current point in time + * \param et A pointer to the event timer. + * + * This function restarts the event timer with the same + * interval that was given to the oc_etimer_set() + * function. The event timer will start at the current + * time. + * + * \note A periodic timer will drift if this function is + * used to reset it. For periodic timers, use the + * oc_etimer_reset() function instead. + * + * \sa oc_etimer_reset() + */ +void oc_etimer_restart(struct oc_etimer *et); + +/** + * \brief Adjust the expiration time for an event timer + * \param et A pointer to the event timer. + * \param td The time difference to adjust the expiration time with. + * + * This function is used to adjust the time the event + * timer will expire. It can be used to synchronize + * periodic timers without the need to restart the timer + * or change the timer interval. + * + * \note This function should only be used for small + * adjustments. For large adjustments use oc_etimer_set() + * instead. + * + * \note A periodic timer will drift unless the + * oc_etimer_reset() function is used. + * + * \sa oc_etimer_set() + * \sa oc_etimer_reset() + */ +void oc_etimer_adjust(struct oc_etimer *et, int td); + +/** + * \brief Get the expiration time for the event timer. + * \param et A pointer to the event timer + * \return The expiration time for the event timer. + * + * This function returns the expiration time for an event timer. + */ +oc_clock_time_t oc_etimer_expiration_time(struct oc_etimer *et); + +/** + * \brief Get the start time for the event timer. + * \param et A pointer to the event timer + * \return The start time for the event timer. + * + * This function returns the start time (when the timer + * was last set) for an event timer. + */ +oc_clock_time_t oc_etimer_start_time(struct oc_etimer *et); + +/** + * \brief Check if an event timer has expired. + * \param et A pointer to the event timer + * \return Non-zero if the timer has expired, zero otherwise. + * + * This function tests if an event timer has expired and + * returns true or false depending on its status. + */ +int oc_etimer_expired(struct oc_etimer *et); + +/** + * \brief Stop a pending event timer. + * \param et A pointer to the pending event timer. + * + * This function stops an event timer that has previously + * been set with oc_etimer_set() or oc_etimer_reset(). After + * this function has been called, the event timer will not + * emit any event when it expires. + * + */ +void oc_etimer_stop(struct oc_etimer *et); + +/** @} */ + +/** + * \name Functions called from timer interrupts, by the system + * @{ + */ + +/** + * \brief Make the event timer aware that the clock has changed + * + * This function is used to inform the event timer module + * that the system clock has been updated. Typically, this + * function would be called from the timer interrupt + * handler when the clock has ticked. + */ +oc_clock_time_t oc_etimer_request_poll(void); + +/** + * \brief Check if there are any non-expired event timers. + * \return True if there are active event timers, false if there are + * no active timers. + * + * This function checks if there are any active event + * timers that have not expired. + */ +int oc_etimer_pending(void); + +/** + * \brief Get next event timer expiration time. + * \return Next expiration time of all pending event timers. + * If there are no pending event timers this function + * returns 0. + * + * This functions returns next expiration time of all + * pending event timers. + */ +oc_clock_time_t oc_etimer_next_expiration_time(void); + +/** @} */ + +OC_PROCESS_NAME(oc_etimer_process); +#ifdef __cplusplus +} +#endif + +#endif /* OC_ETIMER_H */ +/** @} */ +/** @} */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f88168c2/net/oic/src/util/oc_list.c ---------------------------------------------------------------------- diff --git a/net/oic/src/util/oc_list.c b/net/oic/src/util/oc_list.c new file mode 100644 index 0000000..429f411 --- /dev/null +++ b/net/oic/src/util/oc_list.c @@ -0,0 +1,317 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels <a...@sics.se> + * + */ + +#include "oc_list.h" + +#define NULL 0 + +struct list +{ + struct list *next; +}; + +/*---------------------------------------------------------------------------*/ +/** + * Initialize a list. + * + * This function initalizes a list. The list will be empty after this + * function has been called. + * + * \param list The list to be initialized. + */ +void +oc_list_init(oc_list_t list) +{ + *list = NULL; +} +/*---------------------------------------------------------------------------*/ +/** + * Get a pointer to the first element of a list. + * + * This function returns a pointer to the first element of the + * list. The element will \b not be removed from the list. + * + * \param list The list. + * \return A pointer to the first element on the list. + * + * \sa oc_list_tail() + */ +void * +oc_list_head(oc_list_t list) +{ + return *list; +} +/*---------------------------------------------------------------------------*/ +/** + * Duplicate a list. + * + * This function duplicates a list by copying the list reference, but + * not the elements. + * + * \note This function does \b not copy the elements of the list, but + * merely duplicates the pointer to the first element of the list. + * + * \param dest The destination list. + * \param src The source list. + */ +void +oc_list_copy(oc_list_t dest, oc_list_t src) +{ + *dest = *src; +} +/*---------------------------------------------------------------------------*/ +/** + * Get the tail of a list. + * + * This function returns a pointer to the elements following the first + * element of a list. No elements are removed by this function. + * + * \param list The list + * \return A pointer to the element after the first element on the list. + * + * \sa oc_list_head() + */ +void * +oc_list_tail(oc_list_t list) +{ + struct list *l; + + if (*list == NULL) { + return NULL; + } + + for (l = *list; l->next != NULL; l = l->next) + ; + + return l; +} +/*---------------------------------------------------------------------------*/ +/** + * Add an item at the end of a list. + * + * This function adds an item to the end of the list. + * + * \param list The list. + * \param item A pointer to the item to be added. + * + * \sa oc_list_push() + * + */ +void +oc_list_add(oc_list_t list, void *item) +{ + struct list *l; + + /* Make sure not to add the same element twice */ + oc_list_remove(list, item); + + ((struct list *)item)->next = NULL; + + l = oc_list_tail(list); + + if (l == NULL) { + *list = item; + } else { + l->next = item; + } +} +/*---------------------------------------------------------------------------*/ +/** + * Add an item to the start of the list. + */ +void +oc_list_push(oc_list_t list, void *item) +{ + /* Make sure not to add the same element twice */ + oc_list_remove(list, item); + + ((struct list *)item)->next = *list; + *list = item; +} +/*---------------------------------------------------------------------------*/ +/** + * Remove the last object on the list. + * + * This function removes the last object on the list and returns it. + * + * \param list The list + * \return The removed object + * + */ +void * +oc_list_chop(oc_list_t list) +{ + struct list *l, *r; + + if (*list == NULL) { + return NULL; + } + if (((struct list *)*list)->next == NULL) { + l = *list; + *list = NULL; + return l; + } + + for (l = *list; l->next->next != NULL; l = l->next) + ; + + r = l->next; + l->next = NULL; + + return r; +} +/*---------------------------------------------------------------------------*/ +/** + * Remove the first object on a list. + * + * This function removes the first object on the list and returns a + * pointer to it. + * + * \param list The list. + * \return Pointer to the removed element of list. + */ +/*---------------------------------------------------------------------------*/ +void * +oc_list_pop(oc_list_t list) +{ + struct list *l; + l = *list; + if (*list != NULL) { + *list = ((struct list *)*list)->next; + } + + return l; +} +/*---------------------------------------------------------------------------*/ +/** + * Remove a specific element from a list. + * + * This function removes a specified element from the list. + * + * \param list The list. + * \param item The item that is to be removed from the list. + * + */ +/*---------------------------------------------------------------------------*/ +void +oc_list_remove(oc_list_t list, void *item) +{ + struct list *l, *r; + + if (*list == NULL) { + return; + } + + r = NULL; + for (l = *list; l != NULL; l = l->next) { + if (l == item) { + if (r == NULL) { + /* First on list */ + *list = l->next; + } else { + /* Not first on list */ + r->next = l->next; + } + l->next = NULL; + return; + } + r = l; + } +} +/*---------------------------------------------------------------------------*/ +/** + * Get the length of a list. + * + * This function counts the number of elements on a specified list. + * + * \param list The list. + * \return The length of the list. + */ +/*---------------------------------------------------------------------------*/ +int +oc_list_length(oc_list_t list) +{ + struct list *l; + int n = 0; + + for (l = *list; l != NULL; l = l->next) { + ++n; + } + + return n; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Insert an item after a specified item on the list + * \param list The list + * \param previtem The item after which the new item should be inserted + * \param newitem The new item that is to be inserted + * \author Adam Dunkels + * + * This function inserts an item right after a specified + * item on the list. This function is useful when using + * the list module to ordered lists. + * + * If previtem is NULL, the new item is placed at the + * start of the list. + * + */ +void +oc_list_insert(oc_list_t list, void *previtem, void *newitem) +{ + if (previtem == NULL) { + oc_list_push(list, newitem); + } else { + + ((struct list *)newitem)->next = ((struct list *)previtem)->next; + ((struct list *)previtem)->next = newitem; + } +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Get the next item following this item + * \param item A list item + * \returns A next item on the list + * + * This function takes a list item and returns the next + * item on the list, or NULL if there are no more items on + * the list. This function is used when iterating through + * lists. + */ +void * +oc_list_item_next(void *item) +{ + return item == NULL ? NULL : ((struct list *)item)->next; +} +/*---------------------------------------------------------------------------*/ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f88168c2/net/oic/src/util/oc_list.h ---------------------------------------------------------------------- diff --git a/net/oic/src/util/oc_list.h b/net/oic/src/util/oc_list.h new file mode 100644 index 0000000..c0f5db8 --- /dev/null +++ b/net/oic/src/util/oc_list.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels <a...@sics.se> + * + */ + +/** + * \defgroup list Linked list library + * + * The linked list library provides a set of functions for + * manipulating linked lists. + * + * A linked list is made up of elements where the first element \b + * must be a pointer. This pointer is used by the linked list library + * to form lists of the elements. + * + * Lists are declared with the LIST() macro. The declaration specifies + * the name of the list that later is used with all list functions. + * + * Lists can be manipulated by inserting or removing elements from + * either sides of the list (list_push(), list_add(), list_pop(), + * list_chop()). A specified element can also be removed from inside a + * list with list_remove(). The head and tail of a list can be + * extracted using list_head() and list_tail(), respectively. + * + */ + +#ifndef OC_LIST_H +#define OC_LIST_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define OC_LIST_CONCAT2(s1, s2) s1##s2 +#define OC_LIST_CONCAT(s1, s2) OC_LIST_CONCAT2(s1, s2) + +/** + * Declare a linked list. + * + * This macro declares a linked list with the specified \c type. The + * type \b must be a structure (\c struct) with its first element + * being a pointer. This pointer is used by the linked list library to + * form the linked lists. + * + * The list variable is declared as static to make it easy to use in a + * single C module without unnecessarily exporting the name to other + * modules. + * + * \param name The name of the list. + */ +#define OC_LIST(name) \ + static void *OC_LIST_CONCAT(name, _list) = NULL; \ + static oc_list_t name = (oc_list_t)&OC_LIST_CONCAT(name, _list) + +/** + * Declare a linked list inside a structure declaraction. + * + * This macro declares a linked list with the specified \c type. The + * type \b must be a structure (\c struct) with its first element + * being a pointer. This pointer is used by the linked list library to + * form the linked lists. + * + * Internally, the list is defined as two items: the list itself and a + * pointer to the list. The pointer has the name of the parameter to + * the macro and the name of the list is a concatenation of the name + * and the suffix "_list". The pointer must point to the list for the + * list to work. Thus the list must be initialized before using. + * + * The list is initialized with the LIST_STRUCT_INIT() macro. + * + * \param name The name of the list. + */ +#define OC_LIST_STRUCT(name) \ + void *OC_LIST_CONCAT(name, _list); \ + oc_list_t name + +/** + * Initialize a linked list that is part of a structure. + * + * This macro sets up the internal pointers in a list that has been + * defined as part of a struct. This macro must be called before using + * the list. + * + * \param struct_ptr A pointer to the struct + * \param name The name of the list. + */ +#define OC_LIST_STRUCT_INIT(struct_ptr, name) \ + do { \ + (struct_ptr)->name = &((struct_ptr)->OC_LIST_CONCAT(name, _list)); \ + (struct_ptr)->OC_LIST_CONCAT(name, _list) = NULL; \ + oc_list_init((struct_ptr)->name); \ + } while (0) + +/** + * The linked list type. + * + */ +typedef void **oc_list_t; + +void oc_list_init(oc_list_t list); +void *oc_list_head(oc_list_t list); +void *oc_list_tail(oc_list_t list); +void *oc_list_pop(oc_list_t list); +void oc_list_push(oc_list_t list, void *item); + +void *oc_list_chop(oc_list_t list); + +void oc_list_add(oc_list_t list, void *item); +void oc_list_remove(oc_list_t list, void *item); + +int oc_list_length(oc_list_t list); + +void oc_list_copy(oc_list_t dest, oc_list_t src); + +void oc_list_insert(oc_list_t list, void *previtem, void *newitem); + +void *oc_list_item_next(void *item); + +#ifdef __cplusplus +} +#endif + +#endif /* OC_LIST_H */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f88168c2/net/oic/src/util/oc_memb.c ---------------------------------------------------------------------- diff --git a/net/oic/src/util/oc_memb.c b/net/oic/src/util/oc_memb.c new file mode 100644 index 0000000..31909a9 --- /dev/null +++ b/net/oic/src/util/oc_memb.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels <a...@sics.se> + * + */ + +#include "oc_memb.h" +#include <string.h> + +/*---------------------------------------------------------------------------*/ +void +oc_memb_init(struct oc_memb *m) +{ + memset(m->count, 0, m->num); + memset(m->mem, 0, (unsigned)m->size * (unsigned)m->num); +} +/*---------------------------------------------------------------------------*/ +void * +oc_memb_alloc(struct oc_memb *m) +{ + int i; + + for (i = 0; i < m->num; ++i) { + if (m->count[i] == 0) { + /* If this block was unused, we increase the reference count to + indicate that it now is used and return a pointer to the + memory block. */ + ++(m->count[i]); + return (void *)((char *)m->mem + (i * m->size)); + } + } + + /* No free block was found, so we return NULL to indicate failure to + allocate block. */ + return NULL; +} +/*---------------------------------------------------------------------------*/ +char +oc_memb_free(struct oc_memb *m, void *ptr) +{ + int i; + char *ptr2; + + /* Walk through the list of blocks and try to find the block to + which the pointer "ptr" points to. */ + ptr2 = (char *)m->mem; + for (i = 0; i < m->num; ++i) { + + if (ptr2 == (char *)ptr) { + /* We've found to block to which "ptr" points so we decrease the + reference count and return the new value of it. */ + if (m->count[i] > 0) { + /* Make sure that we don't deallocate free memory. */ + --(m->count[i]); + } + return m->count[i]; + } + ptr2 += m->size; + } + return -1; +} +/*---------------------------------------------------------------------------*/ +int +oc_memb_inmemb(struct oc_memb *m, void *ptr) +{ + return (char *)ptr >= (char *)m->mem && + (char *)ptr < (char *)m->mem + (m->num * m->size); +} +/*---------------------------------------------------------------------------*/ +int +oc_memb_numfree(struct oc_memb *m) +{ + int i; + int num_free = 0; + + for (i = 0; i < m->num; ++i) { + if (m->count[i] == 0) { + ++num_free; + } + } + + return num_free; +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f88168c2/net/oic/src/util/oc_memb.h ---------------------------------------------------------------------- diff --git a/net/oic/src/util/oc_memb.h b/net/oic/src/util/oc_memb.h new file mode 100644 index 0000000..37ecca6 --- /dev/null +++ b/net/oic/src/util/oc_memb.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels <a...@sics.se> + * + */ + +/** + * \defgroup memb Memory block management functions + * + * The memory block allocation routines provide a simple yet powerful + * set of functions for managing a set of memory blocks of fixed + * size. A set of memory blocks is statically declared with the + * OC_MEMB() macro. Memory blocks are allocated from the declared + * memory by the oc_memb_alloc() function, and are deallocated with the + * oc_memb_free() function. + * + */ + +#ifndef OC_MEMB_H +#define OC_MEMB_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define CC_CONCAT2(s1, s2) s1##s2 +/** + * A C preprocessing macro for concatenating two preprocessor tokens. + * + * We need use two macros (CC_CONCAT and CC_CONCAT2) in order to allow + * concatenation of two \#defined macros. + */ +#define CC_CONCAT(s1, s2) CC_CONCAT2(s1, s2) + +/** + * Declare a memory block. + * + * This macro is used to statically declare a block of memory that can + * be used by the block allocation functions. The macro statically + * declares a C array with a size that matches the specified number of + * blocks and their individual sizes. + * + * Example: + \code + MEMB(connections, struct connection, 16); + \endcode + * + * \param name The name of the memory block (later used with + * oc_memb_init(), oc_memb_alloc() and oc_memb_free()). + * + * \param structure The name of the struct that the memory block holds + * + * \param num The total number of memory chunks in the block. + * + */ +#define OC_MEMB(name, structure, num) \ + static char CC_CONCAT(name, _memb_count)[num]; \ + static structure CC_CONCAT(name, _memb_mem)[num]; \ + static struct oc_memb name = { sizeof(structure), num, \ + CC_CONCAT(name, _memb_count), \ + (void *)CC_CONCAT(name, _memb_mem) } + +struct oc_memb +{ + unsigned short size; + unsigned short num; + char *count; + void *mem; +}; + +/** + * Initialize a memory block that was declared with MEMB(). + * + * \param m A memory block previously declared with MEMB(). + */ +void oc_memb_init(struct oc_memb *m); + +/** + * Allocate a memory block from a block of memory declared with MEMB(). + * + * \param m A memory block previously declared with MEMB(). + */ +void *oc_memb_alloc(struct oc_memb *m); + +/** + * Deallocate a memory block from a memory block previously declared + * with MEMB(). + * + * \param m m A memory block previously declared with MEMB(). + * + * \param ptr A pointer to the memory block that is to be deallocated. + * + * \return The new reference count for the memory block (should be 0 + * if successfully deallocated) or -1 if the pointer "ptr" did not + * point to a legal memory block. + */ +char oc_memb_free(struct oc_memb *m, void *ptr); + +int oc_memb_inmemb(struct oc_memb *m, void *ptr); + +int oc_memb_numfree(struct oc_memb *m); + +#ifdef __cplusplus +} +#endif + +#endif /* OC_MEMB_H */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f88168c2/net/oic/src/util/oc_mmem.c ---------------------------------------------------------------------- diff --git a/net/oic/src/util/oc_mmem.c b/net/oic/src/util/oc_mmem.c new file mode 100644 index 0000000..8a129c6 --- /dev/null +++ b/net/oic/src/util/oc_mmem.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +#include "oc_mmem.h" +#include "config.h" +#include "oc_list.h" +#include "port/oc_log.h" +#include <stdint.h> +#include <string.h> + +#if !defined(OC_BYTES_POOL_SIZE) || !defined(OC_INTS_POOL_SIZE) || \ + !defined(OC_DOUBLES_POOL_SIZE) +#error "Please define byte, int, double pool sizes in config.h" +#endif /* ...POOL_SIZE */ + +static double doubles[OC_DOUBLES_POOL_SIZE]; +static int64_t ints[OC_INTS_POOL_SIZE]; +static unsigned char bytes[OC_BYTES_POOL_SIZE]; +static unsigned int avail_bytes, avail_ints, avail_doubles; + +OC_LIST(bytes_list); +OC_LIST(ints_list); +OC_LIST(doubles_list); + +/*---------------------------------------------------------------------------*/ +int +oc_mmem_alloc(struct oc_mmem *m, unsigned int size, pool pool_type) +{ + switch (pool_type) { + case BYTE_POOL: + if (avail_bytes < size) { + return 0; + } + oc_list_add(bytes_list, m); + m->ptr = &bytes[OC_BYTES_POOL_SIZE - avail_bytes]; + m->size = size; + avail_bytes -= size; + break; + case INT_POOL: + if (avail_ints < size) { + return 0; + } + oc_list_add(ints_list, m); + m->ptr = &ints[OC_INTS_POOL_SIZE - avail_ints]; + m->size = size; + avail_ints -= size; + break; + case DOUBLE_POOL: + if (avail_doubles < size) { + return 0; + } + oc_list_add(doubles_list, m); + m->ptr = &doubles[OC_DOUBLES_POOL_SIZE - avail_doubles]; + m->size = size; + avail_doubles -= size; + break; + default: + break; + } + return 1; +} + +void +oc_mmem_free(struct oc_mmem *m, pool pool_type) +{ + struct oc_mmem *n; + + if (m->next != NULL) { + switch (pool_type) { + case BYTE_POOL: + memmove(m->ptr, m->next->ptr, &bytes[OC_BYTES_POOL_SIZE - avail_bytes] - + (unsigned char *)m->next->ptr); + break; + case INT_POOL: + memmove(m->ptr, m->next->ptr, + &ints[OC_INTS_POOL_SIZE - avail_ints] - (int64_t *)m->next->ptr); + break; + case DOUBLE_POOL: + memmove(m->ptr, m->next->ptr, + &doubles[OC_DOUBLES_POOL_SIZE - avail_doubles] - + (double *)m->next->ptr); + break; + default: + return; + break; + } + for (n = m->next; n != NULL; n = n->next) { + n->ptr = (void *)((char *)n->ptr - m->size); + } + } + + switch (pool_type) { + case BYTE_POOL: + avail_bytes += m->size; + oc_list_remove(bytes_list, m); + break; + case INT_POOL: + avail_ints += m->size; + oc_list_remove(ints_list, m); + break; + case DOUBLE_POOL: + avail_doubles += m->size; + oc_list_remove(doubles_list, m); + break; + } +} + +void +oc_mmem_init(void) +{ + static int inited = 0; + if (inited) { + return; + } + oc_list_init(bytes_list); + oc_list_init(ints_list); + oc_list_init(doubles_list); + avail_bytes = OC_BYTES_POOL_SIZE; + avail_ints = OC_INTS_POOL_SIZE; + avail_doubles = OC_DOUBLES_POOL_SIZE; + inited = 1; +} +/*---------------------------------------------------------------------------*/ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f88168c2/net/oic/src/util/oc_mmem.h ---------------------------------------------------------------------- diff --git a/net/oic/src/util/oc_mmem.h b/net/oic/src/util/oc_mmem.h new file mode 100644 index 0000000..bcd170f --- /dev/null +++ b/net/oic/src/util/oc_mmem.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +#ifndef OC_MMEM_H +#define OC_MMEM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define OC_MMEM_PTR(m) (struct oc_mmem *)(m)->ptr + +struct oc_mmem +{ + struct oc_mmem *next; + unsigned int size; + void *ptr; +}; + +typedef enum { BYTE_POOL, INT_POOL, DOUBLE_POOL } pool; + +int oc_mmem_alloc(struct oc_mmem *m, unsigned int size, pool pool_type); +void oc_mmem_free(struct oc_mmem *, pool pool_type); +void oc_mmem_init(void); + +#ifdef __cplusplus +} +#endif + +#endif /* OC_MMEM_H */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f88168c2/net/oic/src/util/oc_process.c ---------------------------------------------------------------------- diff --git a/net/oic/src/util/oc_process.c b/net/oic/src/util/oc_process.c new file mode 100644 index 0000000..47c3282 --- /dev/null +++ b/net/oic/src/util/oc_process.c @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +#include "oc_process.h" +#include "oc_buffer.h" +#include <stdio.h> + +/* + * Pointer to the currently running process structure. + */ +struct oc_process *oc_process_list = NULL; +struct oc_process *oc_process_current = NULL; + +static oc_process_event_t lastevent; + +/* + * Structure used for keeping the queue of active events. + */ +struct event_data +{ + oc_process_event_t ev; + oc_process_data_t data; + struct oc_process *p; +}; + +static oc_process_num_events_t nevents, fevent; +static struct event_data events[OC_PROCESS_CONF_NUMEVENTS]; + +#if OC_PROCESS_CONF_STATS +oc_process_num_events_t process_maxevents; +#endif + +static volatile unsigned char poll_requested; + +#define OC_PROCESS_STATE_NONE 0 +#define OC_PROCESS_STATE_RUNNING 1 +#define OC_PROCESS_STATE_CALLED 2 + +static void call_process(struct oc_process *p, oc_process_event_t ev, + oc_process_data_t data); + +/*---------------------------------------------------------------------------*/ +oc_process_event_t +oc_process_alloc_event(void) +{ + return lastevent++; +} +/*---------------------------------------------------------------------------*/ +void +oc_process_start(struct oc_process *p, oc_process_data_t data) +{ + struct oc_process *q; + + /* First make sure that we don't try to start a process that is + already running. */ + for (q = oc_process_list; q != p && q != NULL; q = q->next) + ; + + /* If we found the process on the process list, we bail out. */ + if (q == p) { + return; + } + /* Put on the procs list.*/ + p->next = oc_process_list; + oc_process_list = p; + p->state = OC_PROCESS_STATE_RUNNING; + PT_INIT(&p->pt); + + /* Post a synchronous initialization event to the process. */ + oc_process_post_synch(p, OC_PROCESS_EVENT_INIT, data); +} +/*---------------------------------------------------------------------------*/ +static void +exit_process(struct oc_process *p, struct oc_process *fromprocess) +{ + register struct oc_process *q; + struct oc_process *old_current = oc_process_current; + + /* Make sure the process is in the process list before we try to + exit it. */ + for (q = oc_process_list; q != p && q != NULL; q = q->next) + ; + if (q == NULL) { + return; + } + + if (oc_process_is_running(p)) { + /* Process was running */ + p->state = OC_PROCESS_STATE_NONE; + + /* + * Post a synchronous event to all processes to inform them that + * this process is about to exit. This will allow services to + * deallocate state associated with this process. + */ + for (q = oc_process_list; q != NULL; q = q->next) { + if (p != q) { + call_process(q, OC_PROCESS_EVENT_EXITED, (oc_process_data_t)p); + } + } + + if (p->thread != NULL && p != fromprocess) { + /* Post the exit event to the process that is about to exit. */ + oc_process_current = p; + p->thread(&p->pt, OC_PROCESS_EVENT_EXIT, NULL); + } + } + + if (p == oc_process_list) { + oc_process_list = oc_process_list->next; + } else { + for (q = oc_process_list; q != NULL; q = q->next) { + if (q->next == p) { + q->next = p->next; + break; + } + } + } + + oc_process_current = old_current; +} +/*---------------------------------------------------------------------------*/ +static void +call_process(struct oc_process *p, oc_process_event_t ev, + oc_process_data_t data) +{ + int ret; + + if ((p->state & OC_PROCESS_STATE_RUNNING) && p->thread != NULL) { + oc_process_current = p; + p->state = OC_PROCESS_STATE_CALLED; + ret = p->thread(&p->pt, ev, data); + if (ret == PT_EXITED || ret == PT_ENDED || ev == OC_PROCESS_EVENT_EXIT) { + exit_process(p, p); + } else { + p->state = OC_PROCESS_STATE_RUNNING; + } + } +} +/*---------------------------------------------------------------------------*/ +void +oc_process_exit(struct oc_process *p) +{ + exit_process(p, OC_PROCESS_CURRENT()); +} +/*---------------------------------------------------------------------------*/ +void +oc_process_init(void) +{ + lastevent = OC_PROCESS_EVENT_MAX; + + nevents = fevent = 0; +#if OC_PROCESS_CONF_STATS + process_maxevents = 0; +#endif /* OC_PROCESS_CONF_STATS */ + + oc_process_current = oc_process_list = NULL; +} +/*---------------------------------------------------------------------------*/ +/* + * Call each process' poll handler. + */ +/*---------------------------------------------------------------------------*/ +static void +do_poll(void) +{ + struct oc_process *p; + + poll_requested = 0; + /* Call the processes that needs to be polled. */ + for (p = oc_process_list; p != NULL; p = p->next) { + if (p->needspoll) { + p->state = OC_PROCESS_STATE_RUNNING; + p->needspoll = 0; + call_process(p, OC_PROCESS_EVENT_POLL, NULL); + } + } +} +/*---------------------------------------------------------------------------*/ +/* + * Process the next event in the event queue and deliver it to + * listening processes. + */ +/*---------------------------------------------------------------------------*/ +static void +do_event(void) +{ + static oc_process_event_t ev; + static oc_process_data_t data; + static struct oc_process *receiver; + static struct oc_process *p; + + /* + * If there are any events in the queue, take the first one and walk + * through the list of processes to see if the event should be + * delivered to any of them. If so, we call the event handler + * function for the process. We only process one event at a time and + * call the poll handlers inbetween. + */ + + if (nevents > 0) { + + /* There are events that we should deliver. */ + ev = events[fevent].ev; + + data = events[fevent].data; + receiver = events[fevent].p; + + /* Since we have seen the new event, we move pointer upwards + and decrease the number of events. */ + fevent = (fevent + 1) % OC_PROCESS_CONF_NUMEVENTS; + --nevents; + + /* If this is a broadcast event, we deliver it to all events, in + order of their priority. */ + if (receiver == OC_PROCESS_BROADCAST) { + for (p = oc_process_list; p != NULL; p = p->next) { + + /* If we have been requested to poll a process, we do this in + between processing the broadcast event. */ + if (poll_requested) { + do_poll(); + } + call_process(p, ev, data); + } + } else { + /* This is not a broadcast event, so we deliver it to the + specified process. */ + /* If the event was an INIT event, we should also update the + state of the process. */ + if (ev == OC_PROCESS_EVENT_INIT) { + receiver->state = OC_PROCESS_STATE_RUNNING; + } + + /* Make sure that the process actually is running. */ + call_process(receiver, ev, data); + } + } +} +/*---------------------------------------------------------------------------*/ +int +oc_process_run(void) +{ + /* Process poll events. */ + if (poll_requested) { + do_poll(); + } + + /* Process one event from the queue */ + do_event(); + + return nevents + poll_requested; +} +/*---------------------------------------------------------------------------*/ +int +oc_process_nevents(void) +{ + return nevents + poll_requested; +} +/*---------------------------------------------------------------------------*/ +int +oc_process_post(struct oc_process *p, oc_process_event_t ev, + oc_process_data_t data) +{ + static oc_process_num_events_t snum; + + if (nevents == OC_PROCESS_CONF_NUMEVENTS) { + oc_message_unref(data); + return OC_PROCESS_ERR_FULL; + } + + snum = + (oc_process_num_events_t)(fevent + nevents) % OC_PROCESS_CONF_NUMEVENTS; + events[snum].ev = ev; + events[snum].data = data; + events[snum].p = p; + ++nevents; + +#if OC_PROCESS_CONF_STATS + if (nevents > process_maxevents) { + process_maxevents = nevents; + } +#endif /* OC_PROCESS_CONF_STATS */ + + return OC_PROCESS_ERR_OK; +} +/*---------------------------------------------------------------------------*/ +void +oc_process_post_synch(struct oc_process *p, oc_process_event_t ev, + oc_process_data_t data) +{ + struct oc_process *caller = oc_process_current; + + call_process(p, ev, data); + oc_process_current = caller; +} +/*---------------------------------------------------------------------------*/ +void +oc_process_poll(struct oc_process *p) +{ + if (p != NULL) { + if (p->state == OC_PROCESS_STATE_RUNNING || + p->state == OC_PROCESS_STATE_CALLED) { + p->needspoll = 1; + poll_requested = 1; + } + } +} +/*---------------------------------------------------------------------------*/ +int +oc_process_is_running(struct oc_process *p) +{ + return p->state != OC_PROCESS_STATE_NONE; +} +/*---------------------------------------------------------------------------*/ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f88168c2/net/oic/src/util/oc_process.h ---------------------------------------------------------------------- diff --git a/net/oic/src/util/oc_process.h b/net/oic/src/util/oc_process.h new file mode 100644 index 0000000..b81e217 --- /dev/null +++ b/net/oic/src/util/oc_process.h @@ -0,0 +1,535 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \defgroup process Contiki processes + * + * A process in Contiki consists of a single \ref pt "protothread". + * + * @{ + */ + +#ifndef OC_PROCESS_H +#define OC_PROCESS_H +#include "pt/pt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef NULL +#define NULL 0 +#endif /* NULL */ + +typedef unsigned char oc_process_event_t; +typedef void *oc_process_data_t; +typedef unsigned char oc_process_num_events_t; + +/** + * \name Return values + * @{ + */ + +/** + * \brief Return value indicating that an operation was successful. + * + * This value is returned to indicate that an operation + * was successful. + */ +#define OC_PROCESS_ERR_OK 0 +/** + * \brief Return value indicating that the event queue was full. + * + * This value is returned from process_post() to indicate + * that the event queue was full and that an event could + * not be posted. + */ +#define OC_PROCESS_ERR_FULL 1 +/* @} */ + +#define OC_PROCESS_NONE NULL + +#ifndef OC_PROCESS_CONF_NUMEVENTS +#define OC_PROCESS_CONF_NUMEVENTS 10 +#endif /* OC_PROCESS_CONF_NUMEVENTS */ + +#define OC_PROCESS_EVENT_NONE 0x80 +#define OC_PROCESS_EVENT_INIT 0x81 +#define OC_PROCESS_EVENT_POLL 0x82 +#define OC_PROCESS_EVENT_EXIT 0x83 +#define OC_PROCESS_EVENT_SERVICE_REMOVED 0x84 +#define OC_PROCESS_EVENT_CONTINUE 0x85 +#define OC_PROCESS_EVENT_MSG 0x86 +#define OC_PROCESS_EVENT_EXITED 0x87 +#define OC_PROCESS_EVENT_TIMER 0x88 +#define OC_PROCESS_EVENT_COM 0x89 +#define OC_PROCESS_EVENT_MAX 0x8a + +#define OC_PROCESS_BROADCAST NULL +#define OC_PROCESS_ZOMBIE ((struct oc_process *)0x1) + +/** + * \name Process protothread functions + * @{ + */ + +/** + * Define the beginning of a process. + * + * This macro defines the beginning of a process, and must always + * appear in a OC_PROCESS_THREAD() definition. The OC_PROCESS_END() macro + * must come at the end of the process. + * + * \hideinitializer + */ +#define OC_PROCESS_BEGIN() PT_BEGIN(process_pt) + +/** + * Define the end of a process. + * + * This macro defines the end of a process. It must appear in a + * OC_PROCESS_THREAD() definition and must always be included. The + * process exits when the OC_PROCESS_END() macro is reached. + * + * \hideinitializer + */ +#define OC_PROCESS_END() PT_END(process_pt) + +/** + * Wait for an event to be posted to the process. + * + * This macro blocks the currently running process until the process + * receives an event. + * + * \hideinitializer + */ +#define OC_PROCESS_WAIT_EVENT() OC_PROCESS_YIELD() + +/** + * Wait for an event to be posted to the process, with an extra + * condition. + * + * This macro is similar to OC_PROCESS_WAIT_EVENT() in that it blocks the + * currently running process until the process receives an event. But + * OC_PROCESS_WAIT_EVENT_UNTIL() takes an extra condition which must be + * true for the process to continue. + * + * \param c The condition that must be true for the process to continue. + * \sa PT_WAIT_UNTIL() + * + * \hideinitializer + */ +#define OC_PROCESS_WAIT_EVENT_UNTIL(c) OC_PROCESS_YIELD_UNTIL(c) + +/** + * Yield the currently running process. + * + * \hideinitializer + */ +#define OC_PROCESS_YIELD() PT_YIELD(process_pt) + +/** + * Yield the currently running process until a condition occurs. + * + * This macro is different from OC_PROCESS_WAIT_UNTIL() in that + * OC_PROCESS_YIELD_UNTIL() is guaranteed to always yield at least + * once. This ensures that the process does not end up in an infinite + * loop and monopolizing the CPU. + * + * \param c The condition to wait for. + * + * \hideinitializer + */ +#define OC_PROCESS_YIELD_UNTIL(c) PT_YIELD_UNTIL(process_pt, c) + +/** + * Wait for a condition to occur. + * + * This macro does not guarantee that the process yields, and should + * therefore be used with care. In most cases, OC_PROCESS_WAIT_EVENT(), + * OC_PROCESS_WAIT_EVENT_UNTIL(), OC_PROCESS_YIELD() or + * OC_PROCESS_YIELD_UNTIL() should be used instead. + * + * \param c The condition to wait for. + * + * \hideinitializer + */ +#define OC_PROCESS_WAIT_UNTIL(c) PT_WAIT_UNTIL(process_pt, c) +#define OC_PROCESS_WAIT_WHILE(c) PT_WAIT_WHILE(process_pt, c) + +/** + * Exit the currently running process. + * + * \hideinitializer + */ +#define OC_PROCESS_EXIT() PT_EXIT(process_pt) + +/** + * Spawn a protothread from the process. + * + * \param pt The protothread state (struct pt) for the new protothread + * \param thread The call to the protothread function. + * \sa PT_SPAWN() + * + * \hideinitializer + */ +#define OC_PROCESS_PT_SPAWN(pt, thread) PT_SPAWN(process_pt, pt, thread) + +/** + * Yield the process for a short while. + * + * This macro yields the currently running process for a short while, + * thus letting other processes run before the process continues. + * + * \hideinitializer + */ +#define OC_PROCESS_PAUSE() \ + do { \ + process_post(OC_PROCESS_CURRENT(), OC_PROCESS_EVENT_CONTINUE, NULL); \ + OC_PROCESS_WAIT_EVENT_UNTIL(ev == OC_PROCESS_EVENT_CONTINUE); \ + } while (0) + +/** @} end of protothread functions */ + +/** + * \name Poll and exit handlers + * @{ + */ +/** + * Specify an action when a process is polled. + * + * \note This declaration must come immediately before the + * OC_PROCESS_BEGIN() macro. + * + * \param handler The action to be performed. + * + * \hideinitializer + */ +#define OC_PROCESS_POLLHANDLER(handler) \ + if (ev == OC_PROCESS_EVENT_POLL) { \ + handler; \ + } + +/** + * Specify an action when a process exits. + * + * \note This declaration must come immediately before the + * OC_PROCESS_BEGIN() macro. + * + * \param handler The action to be performed. + * + * \hideinitializer + */ +#define OC_PROCESS_EXITHANDLER(handler) \ + if (ev == OC_PROCESS_EVENT_EXIT) { \ + handler; \ + } + +/** @} */ + +/** + * \name Process declaration and definition + * @{ + */ + +/** + * Define the body of a process. + * + * This macro is used to define the body (protothread) of a + * process. The process is called whenever an event occurs in the + * system, A process always start with the OC_PROCESS_BEGIN() macro and + * end with the OC_PROCESS_END() macro. + * + * \hideinitializer + */ +#define OC_PROCESS_THREAD(name, ev, data) \ + static PT_THREAD(process_thread_##name( \ + struct pt *process_pt, oc_process_event_t ev, oc_process_data_t data)) + +/** + * Declare the name of a process. + * + * This macro is typically used in header files to declare the name of + * a process that is implemented in the C file. + * + * \hideinitializer + */ +#define OC_PROCESS_NAME(name) extern struct oc_process name + +/** + * Declare a process. + * + * This macro declares a process. The process has two names: the + * variable of the process structure, which is used by the C program, + * and a human readable string name, which is used when debugging. + * A configuration option allows removal of the readable name to save RAM. + * + * \param name The variable name of the process structure. + * \param strname The string representation of the process' name. + * + * \hideinitializer + */ +#if OC_PROCESS_CONF_NO_OC_PROCESS_NAMES +#define OC_PROCESS(name, strname) \ + OC_PROCESS_THREAD(name, ev, data); \ + struct oc_process name = { NULL, process_thread_##name } +#else +#define OC_PROCESS(name, strname) \ + OC_PROCESS_THREAD(name, ev, data); \ + struct oc_process name = { NULL, strname, process_thread_##name } +#endif + +/** @} */ + +struct oc_process +{ + struct oc_process *next; +#if OC_PROCESS_CONF_NO_OC_PROCESS_NAMES +#define OC_PROCESS_NAME_STRING(process) "" +#else + const char *name; +#define OC_PROCESS_NAME_STRING(process) (process)->name +#endif + PT_THREAD((*thread)(struct pt *, oc_process_event_t, oc_process_data_t)); + struct pt pt; + unsigned char state, needspoll; +}; + +/** + * \name Functions called from application programs + * @{ + */ + +/** + * Start a process. + * + * \param p A pointer to a process structure. + * + * \param data An argument pointer that can be passed to the new + * process + * + */ +void oc_process_start(struct oc_process *p, oc_process_data_t data); + +/** + * Post an asynchronous event. + * + * This function posts an asynchronous event to one or more + * processes. The handing of the event is deferred until the target + * process is scheduled by the kernel. An event can be broadcast to + * all processes, in which case all processes in the system will be + * scheduled to handle the event. + * + * \param ev The event to be posted. + * + * \param data The auxiliary data to be sent with the event + * + * \param p The process to which the event should be posted, or + * OC_PROCESS_BROADCAST if the event should be posted to all processes. + * + * \retval OC_PROCESS_ERR_OK The event could be posted. + * + * \retval OC_PROCESS_ERR_FULL The event queue was full and the event could + * not be posted. + */ +int oc_process_post(struct oc_process *p, oc_process_event_t ev, + oc_process_data_t data); + +/** + * Post a synchronous event to a process. + * + * \param p A pointer to the process' process structure. + * + * \param ev The event to be posted. + * + * \param data A pointer to additional data that is posted together + * with the event. + */ +void oc_process_post_synch(struct oc_process *p, oc_process_event_t ev, + oc_process_data_t data); + +/** + * \brief Cause a process to exit + * \param p The process that is to be exited + * + * This function causes a process to exit. The process can + * either be the currently executing process, or another + * process that is currently running. + * + * \sa OC_PROCESS_CURRENT() + */ +void oc_process_exit(struct oc_process *p); + +/** + * Get a pointer to the currently running process. + * + * This macro get a pointer to the currently running + * process. Typically, this macro is used to post an event to the + * current process with process_post(). + * + * \hideinitializer + */ +#define OC_PROCESS_CURRENT() oc_process_current +extern struct oc_process *oc_process_current; + +/** + * Switch context to another process + * + * This function switch context to the specified process and executes + * the code as if run by that process. Typical use of this function is + * to switch context in services, called by other processes. Each + * OC_PROCESS_CONTEXT_BEGIN() must be followed by the + * OC_PROCESS_CONTEXT_END() macro to end the context switch. + * + * Example: + \code + OC_PROCESS_CONTEXT_BEGIN(&test_process); + etimer_set(&timer, CLOCK_SECOND); + OC_PROCESS_CONTEXT_END(&test_process); + \endcode + * + * \param p The process to use as context + * + * \sa OC_PROCESS_CONTEXT_END() + * \sa OC_PROCESS_CURRENT() + */ +#define OC_PROCESS_CONTEXT_BEGIN(p) \ + { \ + struct oc_process *tmp_current = OC_PROCESS_CURRENT(); \ + oc_process_current = p + +/** + * End a context switch + * + * This function ends a context switch and changes back to the + * previous process. + * + * \param p The process used in the context switch + * + * \sa OC_PROCESS_CONTEXT_START() + */ +#define OC_PROCESS_CONTEXT_END(p) \ + oc_process_current = tmp_current; \ + } + +/** + * \brief Allocate a global event number. + * \return The allocated event number + * + * In Contiki, event numbers above 128 are global and may + * be posted from one process to another. This function + * allocates one such event number. + * + * \note There currently is no way to deallocate an allocated event + * number. + */ +oc_process_event_t oc_process_alloc_event(void); + +/** @} */ + +/** + * \name Functions called from device drivers + * @{ + */ + +/** + * Request a process to be polled. + * + * This function typically is called from an interrupt handler to + * cause a process to be polled. + * + * \param p A pointer to the process' process structure. + */ +void oc_process_poll(struct oc_process *p); + +/** @} */ + +/** + * \name Functions called by the system and boot-up code + * @{ + */ + +/** + * \brief Initialize the process module. + * + * This function initializes the process module and should + * be called by the system boot-up code. + */ +void oc_process_init(void); + +/** + * Run the system once - call poll handlers and process one event. + * + * This function should be called repeatedly from the main() program + * to actually run the Contiki system. It calls the necessary poll + * handlers, and processes one event. The function returns the number + * of events that are waiting in the event queue so that the caller + * may choose to put the CPU to sleep when there are no pending + * events. + * + * \return The number of events that are currently waiting in the + * event queue. + */ +int oc_process_run(void); + +/** + * Check if a process is running. + * + * This function checks if a specific process is running. + * + * \param p The process. + * \retval Non-zero if the process is running. + * \retval Zero if the process is not running. + */ +int oc_process_is_running(struct oc_process *p); + +/** + * Number of events waiting to be processed. + * + * \return The number of events that are currently waiting to be + * processed. + */ +int oc_process_nevents(void); + +/** @} */ + +extern struct oc_process *oc_process_list; + +#define OC_PROCESS_LIST() oc_process_list + +#ifdef __cplusplus +} +#endif + +#endif /* OC_PROCESS_H */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f88168c2/net/oic/src/util/oc_timer.c ---------------------------------------------------------------------- diff --git a/net/oic/src/util/oc_timer.c b/net/oic/src/util/oc_timer.c new file mode 100644 index 0000000..5372f0b --- /dev/null +++ b/net/oic/src/util/oc_timer.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels <a...@sics.se> + * + */ + +#include "oc_timer.h" + +/*---------------------------------------------------------------------------*/ +/** + * Set a timer. + * + * This function is used to set a timer for a time sometime in the + * future. The function oc_timer_expired() will evaluate to true after + * the timer has expired. + * + * \param t A pointer to the timer + * \param interval The interval before the timer expires. + * + */ +void +oc_timer_set(struct oc_timer *t, oc_clock_time_t interval) +{ + t->interval = interval; + t->start = oc_clock_time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Reset the timer with the same interval. + * + * This function resets the timer with the same interval that was + * given to the oc_timer_set() function. The start point of the interval + * is the exact time that the timer last expired. Therefore, this + * function will cause the timer to be stable over time, unlike the + * oc_timer_restart() function. + * + * \note Must not be executed before timer expired + * + * \param t A pointer to the timer. + * \sa oc_timer_restart() + */ +void +oc_timer_reset(struct oc_timer *t) +{ + t->start += t->interval; +} +/*---------------------------------------------------------------------------*/ +/** + * Restart the timer from the current point in time + * + * This function restarts a timer with the same interval that was + * given to the oc_timer_set() function. The timer will start at the + * current time. + * + * \note A periodic timer will drift if this function is used to reset + * it. For preioric timers, use the oc_timer_reset() function instead. + * + * \param t A pointer to the timer. + * + * \sa oc_timer_reset() + */ +void +oc_timer_restart(struct oc_timer *t) +{ + t->start = oc_clock_time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Check if a timer has expired. + * + * This function tests if a timer has expired and returns true or + * false depending on its status. + * + * \param t A pointer to the timer + * + * \return Non-zero if the timer has expired, zero otherwise. + * + */ +int +oc_timer_expired(struct oc_timer *t) +{ + /* Note: Can not return diff >= t->interval so we add 1 to diff and return + t->interval < diff - required to avoid an internal error in mspgcc. */ + oc_clock_time_t diff = (oc_clock_time() - t->start) + 1; + return t->interval < diff; +} +/*---------------------------------------------------------------------------*/ +/** + * The time until the timer expires + * + * This function returns the time until the timer expires. + * + * \param t A pointer to the timer + * + * \return The time until the timer expires + * + */ +oc_clock_time_t +oc_timer_remaining(struct oc_timer *t) +{ + return t->start + t->interval - oc_clock_time(); +} +/*---------------------------------------------------------------------------*/ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f88168c2/net/oic/src/util/oc_timer.h ---------------------------------------------------------------------- diff --git a/net/oic/src/util/oc_timer.h b/net/oic/src/util/oc_timer.h new file mode 100644 index 0000000..fd6c826 --- /dev/null +++ b/net/oic/src/util/oc_timer.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels <a...@sics.se> + * + */ + +/** + * \defgroup timer Timer library + * + * The Contiki kernel does not provide support for timed + * events. Rather, an application that wants to use timers needs to + * explicitly use the timer library. + * + * The timer library provides functions for setting, resetting and + * restarting timers, and for checking if a timer has expired. An + * application must "manually" check if its timers have expired; this + * is not done automatically. + * + * A timer is declared as a \c struct \c timer and all access to the + * timer is made by a pointer to the declared timer. + * + * \note The timer library is not able to post events when a timer + * expires. The \ref etimer "Event timers" should be used for this + * purpose. + * + * \note The timer library uses the \ref clock "Clock library" to + * measure time. Intervals should be specified in the format used by + * the clock library. + * + * \sa \ref etimer "Event timers" + * + * @{ + */ + +#ifndef OC_TIMER_H +#define OC_TIMER_H + +#include "../port/oc_clock.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * A timer. + * + * This structure is used for declaring a timer. The timer must be set + * with timer_set() before it can be used. + * + * \hideinitializer + */ +struct oc_timer +{ + oc_clock_time_t start; + oc_clock_time_t interval; +}; + +void oc_timer_set(struct oc_timer *t, oc_clock_time_t interval); +void oc_timer_reset(struct oc_timer *t); +void oc_timer_restart(struct oc_timer *t); +int oc_timer_expired(struct oc_timer *t); +oc_clock_time_t oc_timer_remaining(struct oc_timer *t); + +#ifdef __cplusplus +} +#endif + +#endif /* OC_TIMER_H */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f88168c2/net/oic/src/util/pt/lc-addrlabels.h ---------------------------------------------------------------------- diff --git a/net/oic/src/util/pt/lc-addrlabels.h b/net/oic/src/util/pt/lc-addrlabels.h new file mode 100644 index 0000000..68a043e --- /dev/null +++ b/net/oic/src/util/pt/lc-addrlabels.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2004-2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels <a...@sics.se> + * + */ + +/** + * \addtogroup lc + * @{ + */ + +/** + * \file + * Implementation of local continuations based on the "Labels as + * values" feature of gcc + * \author + * Adam Dunkels <a...@sics.se> + * + * This implementation of local continuations is based on a special + * feature of the GCC C compiler called "labels as values". This + * feature allows assigning pointers with the address of the code + * corresponding to a particular C label. + * + * For more information, see the GCC documentation: + * http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html + * + * Thanks to dividuum for finding the nice local scope label + * implementation. + */ + +#ifndef LC_ADDRLABELS_H_ +#define LC_ADDRLABELS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** \hideinitializer */ +typedef void *lc_t; + +#define LC_INIT(s) s = NULL + +#define LC_RESUME(s) \ + do { \ + if (s != NULL) { \ + goto *s; \ + } \ + } while (0) + +#define LC_SET(s) \ + do { \ + ({ \ + __label__ resume; \ + resume: \ + (s) = &&resume; \ + }); \ + } while (0) + +#define LC_END(s) + +#ifdef __cplusplus +} +#endif + +#endif /* LC_ADDRLABELS_H_ */ +/** @} */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f88168c2/net/oic/src/util/pt/lc-switch.h ---------------------------------------------------------------------- diff --git a/net/oic/src/util/pt/lc-switch.h b/net/oic/src/util/pt/lc-switch.h new file mode 100644 index 0000000..7521c25 --- /dev/null +++ b/net/oic/src/util/pt/lc-switch.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2004-2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels <a...@sics.se> + * + */ + +/** + * \addtogroup lc + * @{ + */ + +/** + * \file + * Implementation of local continuations based on switch() statement + * \author Adam Dunkels <a...@sics.se> + * + * This implementation of local continuations uses the C switch() + * statement to resume execution of a function somewhere inside the + * function's body. The implementation is based on the fact that + * switch() statements are able to jump directly into the bodies of + * control structures such as if() or while() statements. + * + * This implementation borrows heavily from Simon Tatham's coroutines + * implementation in C: + * http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html + */ + +#ifndef LC_SWITCH_H_ +#define LC_SWITCH_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* WARNING! lc implementation using switch() does not work if an + LC_SET() is done within another switch() statement! */ + +/** \hideinitializer */ +typedef unsigned short lc_t; + +#define LC_INIT(s) s = 0; + +#define LC_RESUME(s) \ + switch (s) { \ + case 0: + +#define LC_SET(s) \ + s = __LINE__; \ + case __LINE__: + +#define LC_END(s) } + +#ifdef __cplusplus +} +#endif + +#endif /* LC_SWITCH_H_ */ + +/** @} */ http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f88168c2/net/oic/src/util/pt/lc.h ---------------------------------------------------------------------- diff --git a/net/oic/src/util/pt/lc.h b/net/oic/src/util/pt/lc.h new file mode 100644 index 0000000..1d2c254 --- /dev/null +++ b/net/oic/src/util/pt/lc.h @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2004-2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels <a...@sics.se> + * + */ + +/** + * \addtogroup pt + * @{ + */ + +/** + * \defgroup lc Local continuations + * @{ + * + * Local continuations form the basis for implementing protothreads. A + * local continuation can be <i>set</i> in a specific function to + * capture the state of the function. After a local continuation has + * been set can be <i>resumed</i> in order to restore the state of the + * function at the point where the local continuation was set. + * + * + */ + +/** + * \file core/sys/lc.h + * Local continuations + * \author + * Adam Dunkels <a...@sics.se> + * + */ + +#ifdef DOXYGEN +/** + * Initialize a local continuation. + * + * This operation initializes the local continuation, thereby + * unsetting any previously set continuation state. + * + * \hideinitializer + */ +#define LC_INIT(lc) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Set a local continuation. + * + * The set operation saves the state of the function at the point + * where the operation is executed. As far as the set operation is + * concerned, the state of the function does <b>not</b> include the + * call-stack or local (automatic) variables, but only the program + * counter and such CPU registers that needs to be saved. + * + * \hideinitializer + */ +#define LC_SET(lc) + +/** + * Resume a local continuation. + * + * The resume operation resumes a previously set local continuation, thus + * restoring the state in which the function was when the local + * continuation was set. If the local continuation has not been + * previously set, the resume operation does nothing. + * + * \hideinitializer + */ +#define LC_RESUME(lc) + +/** + * Mark the end of local continuation usage. + * + * The end operation signifies that local continuations should not be + * used any more in the function. This operation is not needed for + * most implementations of local continuation, but is required by a + * few implementations. + * + * \hideinitializer + */ +#define LC_END(lc) + +/** + * \var typedef lc_t; + * + * The local continuation type. + * + * \hideinitializer + */ +#endif /* DOXYGEN */ + +#ifndef LC_H_ +#define LC_H_ + +#ifdef LC_CONF_INCLUDE +#include LC_CONF_INCLUDE +#else /* LC_CONF_INCLUDE */ +#include "lc-switch.h" +#endif /* LC_CONF_INCLUDE */ + +#ifdef __cplusplus +} +#endif + +#endif /* LC_H_ */ + +/** @} */ +/** @} */