Dependencies:   MMA7660 LM75B

Committer:
MACRUM
Date:
Sat Jun 30 01:40:30 2018 +0000
Revision:
0:119624335925
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MACRUM 0:119624335925 1 // ----------------------------------------------------------------------------
MACRUM 0:119624335925 2 // Copyright 2015-2017 ARM Ltd.
MACRUM 0:119624335925 3 //
MACRUM 0:119624335925 4 // SPDX-License-Identifier: Apache-2.0
MACRUM 0:119624335925 5 //
MACRUM 0:119624335925 6 // Licensed under the Apache License, Version 2.0 (the "License");
MACRUM 0:119624335925 7 // you may not use this file except in compliance with the License.
MACRUM 0:119624335925 8 // You may obtain a copy of the License at
MACRUM 0:119624335925 9 //
MACRUM 0:119624335925 10 // http://www.apache.org/licenses/LICENSE-2.0
MACRUM 0:119624335925 11 //
MACRUM 0:119624335925 12 // Unless required by applicable law or agreed to in writing, software
MACRUM 0:119624335925 13 // distributed under the License is distributed on an "AS IS" BASIS,
MACRUM 0:119624335925 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
MACRUM 0:119624335925 15 // See the License for the specific language governing permissions and
MACRUM 0:119624335925 16 // limitations under the License.
MACRUM 0:119624335925 17 // ----------------------------------------------------------------------------
MACRUM 0:119624335925 18
MACRUM 0:119624335925 19 #include "atomic-queue/atomic-queue.h"
MACRUM 0:119624335925 20 #include "atomic.h"
MACRUM 0:119624335925 21
MACRUM 0:119624335925 22 #include <stddef.h>
MACRUM 0:119624335925 23 #include <stdint.h>
MACRUM 0:119624335925 24 #include <stdio.h>
MACRUM 0:119624335925 25
MACRUM 0:119624335925 26 #define CORE_UTIL_ASSERT_MSG(test, msg)
MACRUM 0:119624335925 27
MACRUM 0:119624335925 28
MACRUM 0:119624335925 29 int aq_push_tail(struct atomic_queue * q, struct atomic_queue_element * e)
MACRUM 0:119624335925 30 {
MACRUM 0:119624335925 31 CORE_UTIL_ASSERT_MSG(q != NULL, "null queue used");
MACRUM 0:119624335925 32 if (q == NULL) {
MACRUM 0:119624335925 33 return ATOMIC_QUEUE_NULL_QUEUE;
MACRUM 0:119624335925 34 }
MACRUM 0:119624335925 35
MACRUM 0:119624335925 36 /* duplicate element check using lock */
MACRUM 0:119624335925 37 #ifdef ATOMIC_QUEUE_CONFIG_ELEMENT_LOCK
MACRUM 0:119624335925 38 uintptr_t lock;
MACRUM 0:119624335925 39 // Check/obtain a lock on the element.
MACRUM 0:119624335925 40 do {
MACRUM 0:119624335925 41 lock = e->lock;
MACRUM 0:119624335925 42 if (lock) {
MACRUM 0:119624335925 43 return ATOMIC_QUEUE_DUPLICATE_ELEMENT;
MACRUM 0:119624335925 44 }
MACRUM 0:119624335925 45 } while (!aq_atomic_cas_uintptr(&e->lock, lock, 1));
MACRUM 0:119624335925 46 #endif
MACRUM 0:119624335925 47
MACRUM 0:119624335925 48 do {
MACRUM 0:119624335925 49 /* duplicate element check by searching */
MACRUM 0:119624335925 50 #ifndef ATOMIC_QUEUE_CONFIG_ELEMENT_LOCK
MACRUM 0:119624335925 51 // Make sure the new element does not exist in the current queue
MACRUM 0:119624335925 52 struct atomic_queue_element* te = q->tail;
MACRUM 0:119624335925 53 while (te != NULL)
MACRUM 0:119624335925 54 {
MACRUM 0:119624335925 55 CORE_UTIL_ASSERT_MSG(te != e, "duplicate queue element");
MACRUM 0:119624335925 56 if (te == e) {
MACRUM 0:119624335925 57 return ATOMIC_QUEUE_DUPLICATE_ELEMENT;
MACRUM 0:119624335925 58 }
MACRUM 0:119624335925 59 te = te->next;
MACRUM 0:119624335925 60 }
MACRUM 0:119624335925 61 #endif
MACRUM 0:119624335925 62 e->next = q->tail;
MACRUM 0:119624335925 63 } while (!aq_atomic_cas_uintptr((uintptr_t *)&q->tail, (uintptr_t)e->next, (uintptr_t)e));
MACRUM 0:119624335925 64
MACRUM 0:119624335925 65 return ATOMIC_QUEUE_SUCCESS;
MACRUM 0:119624335925 66 }
MACRUM 0:119624335925 67
MACRUM 0:119624335925 68 struct atomic_queue_element * aq_pop_head(struct atomic_queue * q)
MACRUM 0:119624335925 69 {
MACRUM 0:119624335925 70 CORE_UTIL_ASSERT_MSG(q != NULL, "null queue used");
MACRUM 0:119624335925 71 if (q == NULL) {
MACRUM 0:119624335925 72 return NULL;
MACRUM 0:119624335925 73 }
MACRUM 0:119624335925 74 struct atomic_queue_element * current;
MACRUM 0:119624335925 75 int fail = AQ_ATOMIC_CAS_DEREF_VALUE;
MACRUM 0:119624335925 76 while (fail != AQ_ATOMIC_CAS_DEREF_SUCCESS) {
MACRUM 0:119624335925 77 // Set the element reference pointer to the tail pointer
MACRUM 0:119624335925 78 struct atomic_queue_element * volatile * px = &q->tail;
MACRUM 0:119624335925 79 if (*px == NULL) {
MACRUM 0:119624335925 80 return NULL;
MACRUM 0:119624335925 81 }
MACRUM 0:119624335925 82 fail = AQ_ATOMIC_CAS_DEREF_VALUE;
MACRUM 0:119624335925 83 while (fail == AQ_ATOMIC_CAS_DEREF_VALUE) {
MACRUM 0:119624335925 84 fail = aq_atomic_cas_deref_uintptr((uintptr_t * volatile *)px,
MACRUM 0:119624335925 85 (uintptr_t **)&current,
MACRUM 0:119624335925 86 (uintptr_t) NULL,
MACRUM 0:119624335925 87 NULL,
MACRUM 0:119624335925 88 offsetof(struct atomic_queue_element, next));
MACRUM 0:119624335925 89 if (fail == AQ_ATOMIC_CAS_DEREF_VALUE) {
MACRUM 0:119624335925 90 if (current->next == q->tail) {
MACRUM 0:119624335925 91 return NULL;
MACRUM 0:119624335925 92 }
MACRUM 0:119624335925 93 px = &current->next;
MACRUM 0:119624335925 94 }
MACRUM 0:119624335925 95 }
MACRUM 0:119624335925 96 }
MACRUM 0:119624335925 97
MACRUM 0:119624335925 98 #ifdef ATOMIC_QUEUE_CONFIG_ELEMENT_LOCK
MACRUM 0:119624335925 99 // Release element lock
MACRUM 0:119624335925 100 current->lock = 0;
MACRUM 0:119624335925 101 #endif
MACRUM 0:119624335925 102
MACRUM 0:119624335925 103 return current;
MACRUM 0:119624335925 104 }
MACRUM 0:119624335925 105
MACRUM 0:119624335925 106
MACRUM 0:119624335925 107 int aq_empty(struct atomic_queue * q)
MACRUM 0:119624335925 108 {
MACRUM 0:119624335925 109 return q->tail == NULL;
MACRUM 0:119624335925 110 }
MACRUM 0:119624335925 111
MACRUM 0:119624335925 112 unsigned aq_count(struct atomic_queue *q)
MACRUM 0:119624335925 113 {
MACRUM 0:119624335925 114 unsigned x;
MACRUM 0:119624335925 115 struct atomic_queue_element * volatile e;
MACRUM 0:119624335925 116 if (aq_empty(q)) {
MACRUM 0:119624335925 117 return 0;
MACRUM 0:119624335925 118 }
MACRUM 0:119624335925 119 e = q->tail;
MACRUM 0:119624335925 120 for (x = 1; e->next != NULL; x++, e = e->next) {
MACRUM 0:119624335925 121 if (e->next == q->tail){
MACRUM 0:119624335925 122 return (unsigned)-1;
MACRUM 0:119624335925 123 }
MACRUM 0:119624335925 124 }
MACRUM 0:119624335925 125 return x;
MACRUM 0:119624335925 126 }
MACRUM 0:119624335925 127
MACRUM 0:119624335925 128 void aq_initialize_element(struct atomic_queue_element* e)
MACRUM 0:119624335925 129 {
MACRUM 0:119624335925 130 #ifdef ATOMIC_QUEUE_CONFIG_ELEMENT_LOCK
MACRUM 0:119624335925 131 e->lock = 0;
MACRUM 0:119624335925 132 #endif
MACRUM 0:119624335925 133 }