/* * 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!"); } } /*-------------------------------------------------------- */