diff options
Diffstat (limited to 'libparc/parc/algol/parc_Object.c')
-rw-r--r-- | libparc/parc/algol/parc_Object.c | 952 |
1 files changed, 0 insertions, 952 deletions
diff --git a/libparc/parc/algol/parc_Object.c b/libparc/parc/algol/parc_Object.c deleted file mode 100644 index 70a24f34..00000000 --- a/libparc/parc/algol/parc_Object.c +++ /dev/null @@ -1,952 +0,0 @@ -/* - * Copyright (c) 2017 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - */ -#include <config.h> - -#include <parc/assert/parc_Assert.h> - -#include <stdio.h> -#include <inttypes.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <sys/errno.h> -#include <pthread.h> -#include <time.h> -#include <sys/time.h> - -#include <stdint.h> -#include <stdbool.h> - -#include <parc/algol/parc_DisplayIndented.h> -#include <parc/algol/parc_Object.h> -#include <parc/algol/parc_Memory.h> -#include <parc/algol/parc_Hash.h> -#include <parc/concurrent/parc_AtomicUint64.h> - -typedef struct parc_object_locking { - pthread_mutex_t lock; - pthread_cond_t notification; - pthread_t locker; -} _PARCObjectLocking; - -/* - * This is the per-object header. - * The size of this structure must be less than or equal to the value used in the parcObject_PrefixLength macro. - */ -typedef struct object_header { -#define PARCObject_HEADER_MAGIC_GUARD_NUMBER 0x0ddFadda - uint32_t magicGuardNumber; - bool isAllocated; - bool barrier; - PARCReferenceCount references; - const PARCObjectDescriptor *descriptor; - - // The locking member points to the locking structure or is NULL if the object does not support locking. - _PARCObjectLocking *locking; - - // Currently every object is lockable, but at some point in the future this will be controlled by the descriptor. - _PARCObjectLocking lock; - - void *data[]; -} _PARCObjectHeader; - -/* - * Increment/decrement a pointer by the given value. - * - * @param [in] base The base pointer. - * @param [in] increment The value of the pointer increment. - * - * @return void* The updated pointer - */ -static inline void * -_pointerAdd(const void *base, const size_t increment) -{ - void *result = (void *) &((char *) base)[increment]; - return result; -} - -/* - * Compute the size of the prefix as the number of bytes necessary - * to fit the object header (with padding), and any additional per-object data, into allocated memory, - * such that the first address after the header and any additional per-object data, - * is aligned according to the value of the alignment parameter. - * - * For example, if the object header is 5 bytes long, and the alignment is 4 (bytes), - * then the necessary number of bytes to fit the header - * (and yet maintain the proper alignment for the first memory location after the header) is 8. - * - * @param [in] alignment Cache alignment - * - * @return The size of the object header as the number of bytes necessary to fit the header (with padding) into allocated memory. - */ -static inline size_t -_parcObject_PrefixLength(const PARCObjectDescriptor *descriptor) -{ - return parcObject_PrefixLength(descriptor->objectAlignment); -} - -/* - * Given the memory address, return a pointer to the corresponding _PARCObjectHeader structure. - * - * @param [in] object The base pointer to the object. - * - * @return A _PARCObjectHeader struct encapsulating the object's header information. - */ -static inline _PARCObjectHeader * -_parcObject_Header(const PARCObject *object) -{ - return _pointerAdd(object, -sizeof(_PARCObjectHeader)); -} - -static inline const PARCObjectDescriptor * -_parcObject_Descriptor(const PARCObject *object) -{ - return (_parcObject_Header(object)->descriptor); -} - -static inline _PARCObjectLocking * -_parcObjectHeader_Locking(const PARCObject *object) -{ - return _parcObject_Header(object)->locking; -} - -static inline bool -_parcObjectHeader_IsValid(const _PARCObjectHeader *header, const PARCObject *object) -{ - bool result = true; - - if ((intptr_t) header >= (intptr_t) object) { - result = false; - } else if (header->magicGuardNumber != PARCObject_HEADER_MAGIC_GUARD_NUMBER) { - result = false; - } else if (header->references == 0) { - result = false; - } - - return result; -} - -/* - * Compute the origin of the allocated memory. - * - * This will be greater than the start of the object header. - * due to alignment requirements causing the object header to be offset from the origin. - */ -static inline void * -_parcObject_Origin(const PARCObject *object) -{ - _PARCObjectHeader *header = _parcObject_Header(object); - - return _pointerAdd(object, -_parcObject_PrefixLength(header->descriptor)); -} - -static inline PARCObjectEquals * -_parcObject_ResolveEquals(const PARCObjectDescriptor *descriptor) -{ - while (descriptor->equals == NULL) { - descriptor = descriptor->super; - } - return descriptor->equals; -} - -static inline PARCObjectCopy * -_parcObject_ResolveCopy(const PARCObjectDescriptor *descriptor) -{ - while (descriptor->copy == NULL) { - descriptor = descriptor->super; - } - return descriptor->copy; -} - -static inline PARCObjectToString * -_parcObject_ResolveToString(const PARCObjectDescriptor *descriptor) -{ - while (descriptor->toString == NULL) { - descriptor = descriptor->super; - } - return descriptor->toString; -} - -static inline PARCObjectToJSON * -_parcObject_ResolveToJSON(const PARCObjectDescriptor *descriptor) -{ - while (descriptor->toJSON == NULL) { - descriptor = descriptor->super; - } - return descriptor->toJSON; -} - -static bool -_parcObject_Destructor(const PARCObjectDescriptor *descriptor, PARCObject **object) -{ - if (descriptor != NULL) { - if (descriptor->destructor != NULL) { - return descriptor->destructor(object); - } else if (descriptor->destroy != NULL) { - descriptor->destroy(object); - } - } - - return true; -} - -static int -_parcObject_Compare(const PARCObject *self, const PARCObject *other) -{ - _PARCObjectHeader *header = _parcObject_Header(self); - size_t length = header->descriptor->objectSize; - int result = memcmp(self, other, length); - return result; -} - -static PARCObject * -_parcObject_Copy(const PARCObject *object) -{ - _PARCObjectHeader *header = _parcObject_Header(object); - size_t length = header->descriptor->objectSize; - - void *result = parcObject_CreateInstanceImpl(header->descriptor); - memcpy(result, object, length); - parcObject_OptionalAssertValid(result); - return result; -} - -static bool -_parcObject_Equals(const PARCObject *x, const PARCObject *y) -{ - _PARCObjectHeader *header = _parcObject_Header(x); - - bool result = memcmp(x, y, header->descriptor->objectSize) == 0; - - return result; -} - -static char * -_parcObject_ToString(const PARCObject *object) -{ - _PARCObjectHeader *header = _parcObject_Header(object); - - char *string; - int nwritten = asprintf(&string, - "Object@%p { .references=%" PRId64 ", .objectLength = %zd, .objectAlignment=%u } data %p\n", - (void *) header, - header->references, header->descriptor->objectSize, header->descriptor->objectAlignment, object); - parcAssertTrue(nwritten >= 0, "Error calling asprintf"); - char *result = parcMemory_StringDuplicate(string, strlen(string)); - free(string); - return result; -} - -static PARCJSON * -_parcObject_ToJSON(const PARCObject *object) -{ - _PARCObjectHeader *prefix = _parcObject_Header(object); - - PARCJSON *json = parcJSON_Create(); - - parcJSON_AddInteger(json, "references", prefix->references); - parcJSON_AddInteger(json, "objectLength", prefix->descriptor->objectSize); - parcJSON_AddInteger(json, "objectAlignment", prefix->descriptor->objectAlignment); - - char *addressString; - int nwritten = asprintf(&addressString, "%p", object); - parcAssertTrue(nwritten >= 0, "Error calling asprintf"); - - parcJSON_AddString(json, "address", addressString); - - return json; -} - -static PARCHashCode -_parcObject_HashCode(const PARCObject *object) -{ - _PARCObjectHeader *header = _parcObject_Header(object); - return parcHashCode_Hash(object, header->descriptor->objectSize); -} - -static void -_parcObject_Display(const PARCObject *object, const int indentation) -{ - parcObject_OptionalAssertValid(object); - - _PARCObjectHeader *header = _parcObject_Header(object); - - parcDisplayIndented_PrintLine(indentation, "PARCObject@%p @%p={ .name=%s .references=%zd }\n", - object, header, header->descriptor->name, header->references); -} - -const PARCObjectDescriptor -parcObject_DescriptorName(PARCObject) = -{ - .name = "PARCObject", - .destroy = NULL, - .destructor = NULL, - .release = NULL, - .copy = _parcObject_Copy, - .toString = _parcObject_ToString, - .equals = _parcObject_Equals, - .compare = _parcObject_Compare, - .hashCode = _parcObject_HashCode, - .toJSON = _parcObject_ToJSON, - .display = _parcObject_Display, - .super = NULL, - .isLockable = true, - .objectSize = 0, - .objectAlignment = sizeof(void *) -}; - -bool -parcObject_IsValid(const PARCObject *object) -{ - bool result = true; - - if (object == NULL) { - result = false; - } else { - if (_parcObjectHeader_IsValid(_parcObject_Header(object), object) == false) { - result = false; - } - } - - return result; -} - -#ifdef PARCLibrary_DISABLE_VALIDATION -# define parcObjectHeader_OptionalAssertValid(_instance_) -#else -# define parcObjectHeader_OptionalAssertValid(_instance_) _parcObjectHeader_AssertValid(_instance_) -#endif - -static inline void -_parcObjectHeader_AssertValid(const _PARCObjectHeader *header, const PARCObject *object) -{ - parcTrapIllegalValueIf(header->magicGuardNumber != PARCObject_HEADER_MAGIC_GUARD_NUMBER, "PARCObject@%p is corrupt.", object); - parcTrapIllegalValueIf(header->descriptor == NULL, "PARCObject@%p descriptor cannot be NULL.", object); - if (header->descriptor->isLockable) { - parcTrapIllegalValueIf(header->locking == NULL, "PARCObject@%p is corrupt. Is Lockable but no locking structure", object); - } -} - -static inline void -_parcObject_AssertValid(const PARCObject *object) -{ - parcTrapIllegalValueIf(object == NULL, "PARCObject must be a non-null pointer."); - - _PARCObjectHeader *header = _parcObject_Header(object); - _parcObjectHeader_AssertValid(header, object); -} - -void -parcObject_AssertValid(const PARCObject *object) -{ - _parcObject_AssertValid(object); -} - -PARCObject * -parcObject_Acquire(const PARCObject *object) -{ - parcObject_OptionalAssertValid(object); - - _PARCObjectHeader *header = _parcObject_Header(object); - - parcAtomicUint64_Increment(&header->references); - - return (PARCObject *) object; -} - -static inline PARCObjectCompare * -_parcObject_ResolveCompare(const PARCObjectDescriptor *descriptor) -{ - while (descriptor->compare == NULL) { - descriptor = descriptor->super; - } - return descriptor->compare; -} - -int -parcObject_Compare(const PARCObject *x, const PARCObject *y) -{ - int result = 0; - if ((x == NULL) || (y == NULL)) { - result = 0; - if (x != NULL) { - result = 1; - } else if (y != NULL) { - result = -1; - } - return result; - } - - parcObject_OptionalAssertValid(x); - parcObject_OptionalAssertValid(y); - - PARCObjectCompare *compare = _parcObject_ResolveCompare(_parcObject_Descriptor(x)); - result = compare(x, y); - - return result; -} - -bool -parcObject_IsInstanceOf(const PARCObject *object, const PARCObjectDescriptor *descriptor) -{ - bool result = false; - - if (object != NULL) { - _PARCObjectHeader *header = _parcObject_Header(object); - - if (_parcObjectHeader_IsValid(header, object)) { - const PARCObjectDescriptor *d = _parcObject_Descriptor(object); - - while (result == false) { - if (d == descriptor) { - result = true; - } - d = d->super; - } - } - } - - return result; -} - -bool -parcObject_Equals(const PARCObject *x, const PARCObject *y) -{ - bool result = false; - - if (x == y) { - result = true; - } else if (x != NULL && y != NULL) { - _PARCObjectHeader *xHeader = _parcObject_Header(x); - _PARCObjectHeader *yHeader = _parcObject_Header(y); - - if (xHeader->descriptor == yHeader->descriptor) { - PARCObjectEquals *equals = _parcObject_ResolveEquals(xHeader->descriptor); - result = equals(x, y); - } - } - - return result; -} - -static inline PARCObjectHashCode * -_parcObject_ResolveHashCode(const PARCObjectDescriptor *descriptor) -{ - while (descriptor->hashCode == NULL) { - descriptor = descriptor->super; - } - return descriptor->hashCode; -} - -PARCHashCode -parcObject_HashCode(const PARCObject *object) -{ - parcObject_OptionalAssertValid(object); - - PARCObjectHashCode *hashCode = _parcObject_ResolveHashCode(_parcObject_Descriptor(object)); - - return hashCode(object); -} - -static inline PARCObjectDisplay * -_parcObject_ResolveDisplay(const PARCObjectDescriptor *descriptor) -{ - while (descriptor->display == NULL) { - descriptor = descriptor->super; - } - return descriptor->display; -} - -void -parcObject_Display(const PARCObject *object, const int indentation) -{ - parcObject_OptionalAssertValid(object); - - PARCObjectDisplay *display = _parcObject_ResolveDisplay(_parcObject_Descriptor(object)); - - display(object, indentation); -} - -char * -parcObject_ToString(const PARCObject *object) -{ - parcObject_OptionalAssertValid(object); - - PARCObjectToString *toString = _parcObject_ResolveToString(_parcObject_Descriptor(object)); - - return toString(object); -} - -PARCJSON * -parcObject_ToJSON(const PARCObject *object) -{ - parcObject_OptionalAssertValid(object); - - PARCObjectToJSON *toJSON = _parcObject_ResolveToJSON(_parcObject_Descriptor(object)); - return toJSON(object); -} - -PARCObject * -parcObject_CreateAndClearInstanceImpl(const PARCObjectDescriptor *descriptor) -{ - PARCObject *result = parcObject_CreateInstanceImpl(descriptor); - memset(result, 0, descriptor->objectSize); - return result; -} - -static pthread_once_t _parcObject_GlobalLockAttributesInitialized = PTHREAD_ONCE_INIT; -static pthread_mutexattr_t _parcObject_GlobalLockAttributes; - -static void -_parcObject_InitializeGobalLockAttributes(void) -{ - pthread_mutexattr_init(&_parcObject_GlobalLockAttributes); - pthread_mutexattr_settype(&_parcObject_GlobalLockAttributes, PTHREAD_MUTEX_ERRORCHECK); -} - -static inline void -_parcObject_InitializeLocking(_PARCObjectLocking *locking) -{ - if (locking != NULL) { - pthread_once(&_parcObject_GlobalLockAttributesInitialized, _parcObject_InitializeGobalLockAttributes); - - pthread_mutex_init(&locking->lock, &_parcObject_GlobalLockAttributes); - pthread_cond_init(&locking->notification, NULL); - - locking->locker = (pthread_t) NULL; - } -} - -static inline _PARCObjectHeader * -_parcObjectHeader_InitAllocated(_PARCObjectHeader *header, const PARCObjectDescriptor *descriptor) -{ - header->magicGuardNumber = PARCObject_HEADER_MAGIC_GUARD_NUMBER; - header->barrier = false; - header->references = 1; - header->descriptor = (PARCObjectDescriptor *) descriptor; - header->isAllocated = true; - - if (header->descriptor->isLockable) { - header->locking = &header->lock; - _parcObject_InitializeLocking(header->locking); - } else { - header->locking = NULL; - } - - return header; -} - -static inline _PARCObjectHeader * -_parcObjectHeader_InitUnallocated(_PARCObjectHeader *header, const PARCObjectDescriptor *descriptor) -{ - _parcObjectHeader_InitAllocated(header, descriptor); - header->isAllocated = false; - - return header; -} - -PARCObject * -parcObject_WrapImpl(void *memory, const PARCObjectDescriptor *descriptor) -{ - size_t prefixLength = _parcObject_PrefixLength(descriptor); - PARCObject *object = _pointerAdd(memory, prefixLength); - - _parcObjectHeader_InitUnallocated(_parcObject_Header(object), descriptor); - - return object; -} - -PARCObject * -parcObject_CreateInstanceImpl(const PARCObjectDescriptor *descriptor) -{ - size_t prefixLength = _parcObject_PrefixLength(descriptor); - size_t totalMemoryLength = prefixLength + descriptor->objectSize; - - void *origin = NULL; - parcMemory_MemAlign(&origin, sizeof(void *), totalMemoryLength); - - if (origin == NULL) { - errno = ENOMEM; - return NULL; - } - - PARCObject *object = _pointerAdd(origin, prefixLength); - - _parcObjectHeader_InitAllocated(_parcObject_Header(object), descriptor); - - errno = 0; - return object; -} - -PARCObject * -parcObject_InitInstanceImpl(PARCObject *object, const PARCObjectDescriptor *descriptor) -{ - _PARCObjectHeader *header = _parcObject_Header(object); - - _parcObjectHeader_InitUnallocated(header, descriptor); - return object; -} - -PARCObject * -parcObject_InitAndClearInstanceImpl(PARCObject *object, const PARCObjectDescriptor *descriptor) -{ - parcObject_InitInstanceImpl(object, descriptor); - - memset(object, 0, descriptor->objectSize); - return object; -} - -PARCObject * -parcObject_Copy(const PARCObject *object) -{ - parcObject_OptionalAssertValid(object); - - PARCObjectCopy *copy = _parcObject_ResolveCopy(_parcObject_Descriptor(object)); - return copy(object); -} - -PARCReferenceCount -parcObject_Release(PARCObject **objectPointer) -{ - PARCObject *object = *objectPointer; - parcObject_OptionalAssertValid(object); - - _PARCObjectHeader *header = _parcObject_Header(object); - - parcTrapIllegalValueIf(header->references == 0, "PARCObject@%p references must be > 0", object); - - PARCReferenceCount result = parcAtomicUint64_Decrement(&header->references); - - if (result == 0) { - if (_parcObject_Destructor(header->descriptor, objectPointer)) { - if (header->locking != NULL) { - pthread_cond_destroy(&header->locking->notification); - } - if (header->isAllocated) { - void *origin = _parcObject_Origin(object); - parcMemory_Deallocate(&origin); - } - parcAssertNotNull(*objectPointer, "Class implementation unnecessarily clears the object pointer."); - } else { - parcAssertNull(*objectPointer, "Class implementation must clear the object pointer."); - } - } - - *objectPointer = NULL; - return result; -} - -PARCReferenceCount -parcObject_GetReferenceCount(const PARCObject *object) -{ - parcObject_OptionalAssertValid(object); - - _PARCObjectHeader *header = _parcObject_Header(object); - - return header->references; -} - -const PARCObjectDescriptor * -parcObject_GetDescriptor(const PARCObject *object) -{ - parcObject_OptionalAssertValid(object); - - _PARCObjectHeader *header = _parcObject_Header(object); - - return header->descriptor; -} - -const PARCObjectDescriptor * -parcObject_SetDescriptor(PARCObject *object, const PARCObjectDescriptor *descriptor) -{ - parcObject_OptionalAssertValid(object); - parcAssertNotNull(descriptor, "PARCObjectDescriptor cannot be NULL."); - - _PARCObjectHeader *header = _parcObject_Header(object); - - const PARCObjectDescriptor *result = header->descriptor; - header->descriptor = (PARCObjectDescriptor *) descriptor; - - return result; -} - -PARCObjectDescriptor * -parcObjectDescriptor_Create(const char *name, - size_t objectSize, - unsigned int objectAlignment, - bool isLockable, - PARCObjectDestructor *destructor, - PARCObjectRelease *release, - PARCObjectCopy *copy, - PARCObjectToString *toString, - PARCObjectEquals *equals, - PARCObjectCompare *compare, - PARCObjectHashCode *hashCode, - PARCObjectToJSON *toJSON, - PARCObjectDisplay *display, - const PARCObjectDescriptor *superType, - PARCObjectTypeState *typeState) -{ - parcAssertNotNull(superType, "Supertype descriptor cannot be NULL."); - - PARCObjectDescriptor *result = parcMemory_AllocateAndClear(sizeof(PARCObjectDescriptor)); - if (result != NULL) { - strncpy(result->name, name, sizeof(result->name) - 1); - result->name[sizeof(result->name) - 1] = 0; - result->destroy = NULL; - result->destructor = destructor; - result->release = release; - result->copy = copy; - result->toString = toString; - result->equals = equals; - result->compare = compare; - result->hashCode = hashCode; - result->toJSON = toJSON; - result->display = display; - result->super = superType; - result->objectSize = objectSize; - result->objectAlignment = objectAlignment; - result->typeState = typeState; - result->isLockable = isLockable; - } - return result; -} - -PARCObjectDescriptor * -parcObjectDescriptor_CreateExtension(const PARCObjectDescriptor *superType, const char *name) -{ - PARCObjectDescriptor *result = parcMemory_AllocateAndClear(sizeof(PARCObjectDescriptor)); - *result = *superType; - strncpy(result->name, name, sizeof(result->name) - 1); - result->name[sizeof(result->name) - 1] = 0; - return result; -} - -PARCObjectTypeState * -parcObjectDescriptor_GetTypeState(const PARCObjectDescriptor *descriptor) -{ - return descriptor->typeState; -} - -const PARCObjectDescriptor * -parcObjectDescriptor_GetSuperType(const PARCObjectDescriptor *descriptor) -{ - return descriptor->super; -} - -bool -parcObjectDescriptor_Destroy(PARCObjectDescriptor **descriptorPointer) -{ - parcMemory_Deallocate(descriptorPointer); - return true; -} - -bool -parcObject_Unlock(const PARCObject *object) -{ - bool result = false; - - parcObject_OptionalAssertValid(object); - - _PARCObjectHeader *header = _parcObject_Header(object); - if (header->references > 0) { - _parcObjectHeader_AssertValid(header, object); - - if (object != NULL) { - _PARCObjectLocking *locking = _parcObjectHeader_Locking(object); - if (locking != NULL) { - locking->locker = (pthread_t) NULL; - result = (pthread_mutex_unlock(&locking->lock) == 0); - - parcAssertTrue(result, "Attempted to unlock an unowned lock."); - } - } - } - return result; -} - -bool -parcObject_Lock(const PARCObject *object) -{ -#ifndef __ANDROID__ - extern int errno; -#endif - bool result = false; - - parcObject_OptionalAssertValid(object); - - if (object != NULL) { - _PARCObjectLocking *locking = _parcObjectHeader_Locking(object); - if (locking != NULL) { - parcTrapCannotObtainLockIf(pthread_equal(locking->locker, pthread_self()), - "Recursive locks on %p are not supported.", object); - - errno = pthread_mutex_lock(&locking->lock); - - if (errno == 0) { - locking->locker = pthread_self(); - result = true; - } - } - } - - return result; -} - -bool -parcObject_TryLock(const PARCObject *object) -{ - bool result = false; - - if (object != NULL) { - parcObject_OptionalAssertValid(object); - - _PARCObjectLocking *locking = _parcObjectHeader_Locking(object); - if (locking != NULL) { - parcTrapCannotObtainLockIf(pthread_equal(locking->locker, pthread_self()), "Recursive locks are not supported."); - - int lockStatus = pthread_mutex_trylock(&locking->lock); - - if (lockStatus == 0) { - result = true; - locking->locker = pthread_self(); - } - } - } - - return result; -} - -bool -parcObject_IsLocked(const PARCObject *object) -{ - parcObject_OptionalAssertValid(object); - bool result = false; - - _PARCObjectLocking *locking = _parcObjectHeader_Locking(object); - if (locking != NULL) { - result = locking->locker != (pthread_t) NULL; - } - - return result; -} - -void -parcObject_Wait(const PARCObject *object) -{ - parcObject_OptionalAssertValid(object); - - _PARCObjectLocking *locking = _parcObjectHeader_Locking(object); - if (locking != NULL) { - pthread_cond_wait(&locking->notification, &locking->lock); - } -} - -bool -parcObject_WaitUntil(const PARCObject *object, const struct timespec *time) -{ - parcObject_OptionalAssertValid(object); - - bool result = false; - - _PARCObjectLocking *locking = _parcObjectHeader_Locking(object); - if (locking != NULL) { - int waitResult = pthread_cond_timedwait(&locking->notification, &locking->lock, time); - if (waitResult == 0) { - result = true; - } - } - - return result; -} - -bool -parcObject_WaitFor(const PARCObject *object, const uint64_t nanoSeconds) -{ - parcObject_OptionalAssertValid(object); - - bool result = false; - - struct timeval now; - gettimeofday(&now, NULL); - - // Convert timeval to timespec. - struct timespec time = { - .tv_sec = now.tv_sec, - .tv_nsec = (now.tv_usec * 1000) - }; - time.tv_nsec += nanoSeconds; - time.tv_sec += time.tv_nsec / 1000000000; - time.tv_nsec = time.tv_nsec % 1000000000; - - _PARCObjectLocking *locking = _parcObjectHeader_Locking(object); - if (locking != NULL) { - int waitResult = pthread_cond_timedwait(&locking->notification, &locking->lock, &time); - - if (waitResult == 0) { - result = true; - } - } - - return result; -} - -void -parcObject_Notify(const PARCObject *object) -{ - parcObject_OptionalAssertValid(object); - - _PARCObjectLocking *locking = _parcObjectHeader_Locking(object); - if (locking != NULL) { - pthread_cond_signal(&locking->notification); - } -} - -void -parcObject_NotifyAll(const PARCObject *object) -{ - parcObject_OptionalAssertValid(object); - - _PARCObjectLocking *locking = _parcObjectHeader_Locking(object); - if (locking != NULL) { - pthread_cond_broadcast(&locking->notification); - } -} - -bool -parcObject_BarrierSet(const PARCObject *object) -{ - _PARCObjectHeader *header = _parcObject_Header(object); - - while (__sync_bool_compare_and_swap(&header->barrier, false, true) == false) { - ; - } - return true; -} - -bool -parcObject_BarrierUnset(const PARCObject *object) -{ - _PARCObjectHeader *header = _parcObject_Header(object); - - while (__sync_bool_compare_and_swap(&header->barrier, true, false) == false) { - ; - } - - return false; -} |