/* * vxworks_partition.c */ #include #include #include #include #include "private.h" static lub_vxworks_partition_t *first_partition; /*-------------------------------------------------------- */ static void lub_vxworks_partition_task_delete_hook(WIND_TCB * pTcb) { lub_vxworks_partition_t **ptr; int tid = (int)pTcb; /* iterate the list of partitions */ taskLock(); for (ptr = &first_partition; *ptr; ptr = &(*ptr)->m_next_partition) { int val = taskVarGet(tid, (int *)&(*ptr)->m_local_heap); if (ERROR != val) { /* destroy this local heap */ lub_partition_destroy_local_heap(&(*ptr)->m_base, (void *)val); /* and remove the task variable */ taskVarDelete(tid, (int *)&(*ptr)->m_local_heap); } } taskUnlock(); } /*-------------------------------------------------------- */ lub_partition_t *lub_partition_create(const lub_partition_spec_t * spec) { lub_vxworks_partition_t *this; this = calloc(sizeof(lub_vxworks_partition_t), 1); if (this) { /* initialise the global mutex */ if (ERROR == semMInit(&this->m_sem, SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE)) { assert(NULL == "semMInit() failed!"); } lub_partition_lock(&this->m_base); /* initialise the local task variable system */ taskVarInit(); /* initialise the base class */ lub_partition_init(&this->m_base, spec); /* add to the list of partitions */ this->m_next_partition = first_partition; first_partition = this; if (this == first_partition) { /* register a task deletion hook */ taskDeleteHookAdd((FUNCPTR) lub_vxworks_partition_task_delete_hook); } lub_partition_unlock(&this->m_base); } return this ? &this->m_base : 0; } /*-------------------------------------------------------- */ void lub_partition_destroy(lub_partition_t * instance) { lub_vxworks_partition_t *this = (void *)instance; lub_vxworks_partition_t **ptr; /* finalise the base class */ lub_partition_fini(&this->m_base); lub_partition_lock(&this->m_base); /* remove from the list of partitions */ for (ptr = &first_partition; *ptr; ptr = &(*ptr)->m_next_partition) { if (&(*ptr)->m_base == instance) { /* remove from list */ *ptr = (*ptr)->m_next_partition; break; } } if (!first_partition) { /* deregister delete hook */ taskDeleteHookDelete((FUNCPTR) lub_vxworks_partition_task_delete_hook); } lub_partition_unlock(&this->m_base); free(this); } /*-------------------------------------------------------- */ lub_heap_t *lub_partition__get_local_heap(lub_partition_t * instance) { lub_vxworks_partition_t *this = (void *)instance; return this->m_local_heap; } /*-------------------------------------------------------- */ void lub_partition__set_local_heap(lub_partition_t * instance, lub_heap_t * heap) { lub_vxworks_partition_t *this = (void *)instance; if (this->m_local_heap) { assert(NULL == "Local heap already exists!"); } /* add this memory to the local task */ taskVarAdd(0, (int *)&this->m_local_heap); /* add set the value */ this->m_local_heap = heap; } /*-------------------------------------------------------- */ void lub_partition_lock(lub_partition_t * instance) { lub_vxworks_partition_t *this = (void *)instance; if (ERROR == semTake(&this->m_sem, WAIT_FOREVER)) { assert(NULL == "semTake() failed!"); } } /*-------------------------------------------------------- */ void lub_partition_unlock(lub_partition_t * instance) { lub_vxworks_partition_t *this = (void *)instance; if (ERROR == semGive(&this->m_sem)) { assert(NULL == "semGive() failed!"); } } /*-------------------------------------------------------- */