Int32 AVSYNC_LockSharedDataStructure ( Int32* key) { if (pAvsyncMPGate && key) key = GateMP_enter (*pAvsyncMPGate); return OSA_SOK; }
/* * ======== ListMP_putTail ======== */ Int ListMP_putTail(ListMP_Handle handle, ListMP_Elem *elem) { ti_sdo_ipc_ListMP_Object *obj = (ti_sdo_ipc_ListMP_Object *)handle; UInt key; UInt16 id; ListMP_Elem *localPrevElem; SharedRegion_SRPtr sharedElem; SharedRegion_SRPtr sharedHead; Bool localPrevElemIsCached; /* prevent another thread or processor from modifying the ListMP */ key = GateMP_enter((GateMP_Handle)obj->gate); id = SharedRegion_getId(elem); if (ti_sdo_ipc_SharedRegion_translate == FALSE) { sharedElem = (SharedRegion_SRPtr)elem; sharedHead = (SharedRegion_SRPtr)&(obj->attrs->head); localPrevElem = (ListMP_Elem *)obj->attrs->head.prev; } else { sharedElem = SharedRegion_getSRPtr(elem, id); sharedHead = SharedRegion_getSRPtr(&(obj->attrs->head), obj->regionId); localPrevElem = SharedRegion_getPtr(obj->attrs->head.prev); } /* Assert that pointer is not NULL */ Assert_isTrue(localPrevElem != NULL, ti_sdo_ipc_Ipc_A_nullPointer); localPrevElemIsCached = SharedRegion_isCacheEnabled( SharedRegion_getId(localPrevElem)); if (localPrevElemIsCached) { Cache_inv(localPrevElem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } /* add the new elem into the list */ elem->next = sharedHead; elem->prev = obj->attrs->head.prev; localPrevElem->next = sharedElem; obj->attrs->head.prev = sharedElem; if (localPrevElemIsCached) { /* Write-back because localPrevElem->next changed */ Cache_wbInv(localPrevElem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } if (obj->cacheEnabled) { /* Write-back because obj->attrs->head.prev changed */ Cache_wbInv(&(obj->attrs->head), sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } if (SharedRegion_isCacheEnabled(id)) { /* Write-back because elem->next & elem->prev changed */ Cache_wbInv(elem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } GateMP_leave((GateMP_Handle)obj->gate, key); return (ListMP_S_SUCCESS); }
/* * ======== SemaphoreMP_post ======== */ Void SemaphoreMP_post(SemaphoreMP_Object *obj) { UInt tskKey; SemaphoreMP_PendElem *elem; IArg gateMPKey; Int status; /* Enter the gate */ gateMPKey = GateMP_enter((GateMP_Handle)obj->gate); if (ListMP_empty((ListMP_Handle)obj->pendQ)) { if (obj->mode == SemaphoreMP_Mode_BINARY) { obj->attrs->count = 1; } else { obj->attrs->count++; } if (obj->cacheEnabled) { Cache_wbInv(obj->attrs, sizeof(SemaphoreMP_Attrs), Cache_Type_ALL, TRUE); } /* Leave the gate */ GateMP_leave((GateMP_Handle)obj->gate, gateMPKey); return; } /* lock task scheduler */ tskKey = Task_disable(); /* dequeue tsk from semaphore queue */ elem = (SemaphoreMP_PendElem *)ListMP_getHead((ListMP_Handle)obj->pendQ); if (elem->procId != MultiProc_self()) { /* Unblock remote task */ status = Notify_sendEvent(elem->procId, 0, SemaphoreMP_notifyEventId, elem->task, TRUE); Assert_isTrue(status >= 0, ti_sdo_ipc_Ipc_A_internal); } else { /* put task back into readyQ */ Task_unblock((Task_Handle)elem->task); } /* Leave the gate */ GateMP_leave((GateMP_Handle)obj->gate, gateMPKey); Task_restore(tskKey); }
/* * ======== ListMP_remove ======== */ Int ListMP_remove(ListMP_Handle handle, ListMP_Elem *elem) { ti_sdo_ipc_ListMP_Object *obj = (ti_sdo_ipc_ListMP_Object *)handle; UInt key; ListMP_Elem *localPrevElem; ListMP_Elem *localNextElem; Bool localPrevElemIsCached, localNextElemIsCached; /* Prevent another thread or processor from modifying the ListMP */ key = GateMP_enter((GateMP_Handle)obj->gate); if (ti_sdo_ipc_SharedRegion_translate == FALSE) { localPrevElem = (ListMP_Elem *)(elem->prev); localNextElem = (ListMP_Elem *)(elem->next); } else { localPrevElem = SharedRegion_getPtr(elem->prev); localNextElem = SharedRegion_getPtr(elem->next); } localPrevElemIsCached = SharedRegion_isCacheEnabled( SharedRegion_getId(localPrevElem)); localNextElemIsCached = SharedRegion_isCacheEnabled( SharedRegion_getId(localNextElem)); if (localPrevElemIsCached) { Cache_inv(localPrevElem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } if (localNextElemIsCached) { Cache_inv(localNextElem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } localPrevElem->next = elem->next; localNextElem->prev = elem->prev; if (localPrevElemIsCached) { Cache_wbInv(localPrevElem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } if (localNextElemIsCached) { Cache_wbInv(localNextElem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } GateMP_leave((GateMP_Handle)obj->gate, key); return (ListMP_S_SUCCESS); }
/* * ======== TransportShm_put ======== * Assuming MessageQ_put is making sure that the arguments are ok */ Bool TransportShm_put(TransportShm_Object *obj, Ptr msg) { Int32 status; Bool retval = TRUE; IArg key; UInt16 id = SharedRegion_getId(msg); /* This transport only deals with messages allocated from SR's */ Assert_isTrue(id != SharedRegion_INVALIDREGIONID, ti_sdo_ipc_SharedRegion_A_regionInvalid); /* writeback invalidate the message */ if (SharedRegion_isCacheEnabled(id)) { Cache_wbInv(msg, ((MessageQ_Msg)(msg))->msgSize, Cache_Type_ALL, TRUE); } /* make sure ListMP_put and sendEvent are done before remote executes */ key = GateMP_enter((GateMP_Handle)obj->gate); /* Put the message on the remoteList */ ListMP_putTail((ListMP_Handle)obj->remoteList, (ListMP_Elem *)msg); /* Notify the remote processor */ status = Notify_sendEvent(obj->remoteProcId, 0, TransportShm_notifyEventId, 0, FALSE); /* check the status of the sendEvent */ if (status < 0) { /* remove the message from the List and return 'FALSE' */ ListMP_remove((ListMP_Handle)obj->remoteList, (ListMP_Elem *)msg); retval = FALSE; } /* leave the gate */ GateMP_leave((GateMP_Handle)obj->gate, key); return (retval); }
/* * ======== ListMP_empty ======== */ Bool ListMP_empty(ListMP_Handle handle) { ti_sdo_ipc_ListMP_Object *obj = (ti_sdo_ipc_ListMP_Object *)handle; Bool flag = FALSE; IArg key; SharedRegion_SRPtr sharedHead; /* prevent another thread or processor from modifying the ListMP */ key = GateMP_enter((GateMP_Handle)obj->gate); if (ti_sdo_ipc_SharedRegion_translate == FALSE) { /* get the SRPtr for the head */ sharedHead = (SharedRegion_SRPtr)&(obj->attrs->head); } else { /* get the SRPtr for the head */ sharedHead = SharedRegion_getSRPtr(&(obj->attrs->head), obj->regionId); } /* if 'next' is ourself, then the ListMP must be empty */ if (obj->attrs->head.next == sharedHead) { flag = TRUE; } if (obj->cacheEnabled) { /* invalidate the head to make sure we are not getting stale data */ Cache_inv(&(obj->attrs->head), sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } /* leave the gate */ GateMP_leave((GateMP_Handle)obj->gate, key); return (flag); }
/* * ======== ListMP_insert ======== */ Int ListMP_insert(ListMP_Handle handle, ListMP_Elem *newElem, ListMP_Elem *curElem) { ti_sdo_ipc_ListMP_Object *obj = (ti_sdo_ipc_ListMP_Object *)handle; UInt key; Int id; ListMP_Elem *localPrevElem; SharedRegion_SRPtr sharedNewElem; SharedRegion_SRPtr sharedCurElem; Bool curElemIsCached, localPrevElemIsCached; /* prevent another thread or processor from modifying the ListMP */ key = GateMP_enter((GateMP_Handle)obj->gate); if (ti_sdo_ipc_SharedRegion_translate == FALSE) { sharedNewElem = (SharedRegion_SRPtr)newElem; sharedCurElem = (SharedRegion_SRPtr)curElem; localPrevElem = (ListMP_Elem *)(curElem->prev); } else { /* get SRPtr for newElem */ id = SharedRegion_getId(newElem); sharedNewElem = SharedRegion_getSRPtr(newElem, id); /* get SRPtr for curElem */ id = SharedRegion_getId(curElem); sharedCurElem = SharedRegion_getSRPtr(curElem, id); } curElemIsCached = SharedRegion_isCacheEnabled(SharedRegion_getId(curElem)); if (curElemIsCached) { Cache_inv(curElem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } /* get Ptr for curElem->prev */ localPrevElem = SharedRegion_getPtr(curElem->prev); localPrevElemIsCached = SharedRegion_isCacheEnabled( SharedRegion_getId(localPrevElem)); if (localPrevElemIsCached) { Cache_inv(localPrevElem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } newElem->next = sharedCurElem; newElem->prev = curElem->prev; localPrevElem->next = sharedNewElem; curElem->prev = sharedNewElem; if (localPrevElemIsCached) { Cache_wbInv(localPrevElem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } /* * The next two Cache_wbInv needs to be done because curElem * and newElem are passed in and maybe already in the cache */ if (curElemIsCached) { /* writeback invalidate current elem structure */ Cache_wbInv(curElem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } if (SharedRegion_isCacheEnabled(SharedRegion_getId(newElem))) { /* writeback invalidate new elem structure */ Cache_wbInv(newElem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } GateMP_leave((GateMP_Handle)obj->gate, key); return (ListMP_S_SUCCESS); }
/* * ======== ListMP_getTail ======== */ Ptr ListMP_getTail(ListMP_Handle handle) { ti_sdo_ipc_ListMP_Object *obj = (ti_sdo_ipc_ListMP_Object *)handle; ListMP_Elem *elem; ListMP_Elem *localHeadPrev; ListMP_Elem *localPrev; Bool localPrevIsCached; UInt key; /* prevent another thread or processor from modifying the ListMP */ key = GateMP_enter((GateMP_Handle)obj->gate); if (ti_sdo_ipc_SharedRegion_translate == FALSE) { localHeadPrev = (ListMP_Elem *)obj->attrs->head.prev; } else { localHeadPrev = SharedRegion_getPtr(obj->attrs->head.prev); } /* Assert that pointer is not NULL */ Assert_isTrue(localHeadPrev != NULL, ti_sdo_ipc_Ipc_A_nullPointer); /* See if the ListMP was empty */ if (localHeadPrev == (ListMP_Elem *)(&(obj->attrs->head))) { /* Empty, return NULL */ elem = NULL; } else { if (SharedRegion_isCacheEnabled(SharedRegion_getId(localHeadPrev))) { /* invalidate elem */ Cache_inv(localHeadPrev, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } if (ti_sdo_ipc_SharedRegion_translate == FALSE) { localPrev = (ListMP_Elem *)localHeadPrev->prev; } else { localPrev = SharedRegion_getPtr(localHeadPrev->prev); } /* Assert that pointer is not NULL */ Assert_isTrue(localPrev != NULL, ti_sdo_ipc_Ipc_A_nullPointer); /* Elem to return */ elem = localHeadPrev; localPrevIsCached = SharedRegion_isCacheEnabled( SharedRegion_getId(localPrev)); if (localPrevIsCached) { Cache_inv(localPrev, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } /* Fix the head of the list prev pointer */ obj->attrs->head.prev = elem->prev; /* Fix the next pointer of the new last elem on the list */ localPrev->next = localHeadPrev->next; if (localPrevIsCached) { Cache_wbInv(localPrev, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } } if (obj->cacheEnabled) { Cache_wbInv(&(obj->attrs->head), sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } GateMP_leave((GateMP_Handle)obj->gate, key); return (elem); }
/* * ======== SemaphoreMP_pend ======== */ Bool SemaphoreMP_pend(SemaphoreMP_Object *obj) { UInt tskKey; SemaphoreMP_PendElem *elem; IArg gateMPKey; /* Check for correct calling context */ Assert_isTrue((BIOS_getThreadType() == BIOS_ThreadType_Task), SemaphoreMP_A_badContext); elem = ThreadLocal_getspecific(SemaphoreMP_pendElemKey); if (elem == NULL) { /* * Choose region zero (instead of the region that contains the * SemaphoreMP) since region zero is always accessible by all cores */ elem = Memory_alloc(SharedRegion_getHeap(0), sizeof(SemaphoreMP_PendElem), 0, NULL); ThreadLocal_setspecific(SemaphoreMP_pendElemKey, elem); } /* Enter the gate */ gateMPKey = GateMP_enter((GateMP_Handle)obj->gate); if (obj->cacheEnabled) { Cache_inv(obj->attrs, sizeof(SemaphoreMP_Attrs), Cache_Type_ALL, TRUE); } /* check semaphore count */ if (obj->attrs->count == 0) { /* lock task scheduler */ tskKey = Task_disable(); /* get task handle and block tsk */ elem->task = (Bits32)Task_self(); elem->procId = MultiProc_self(); Task_block((Task_Handle)elem->task); if (obj->cacheEnabled) { Cache_wbInv(elem, sizeof(SemaphoreMP_PendElem), Cache_Type_ALL, TRUE); } /* add it to pendQ */ ListMP_putTail((ListMP_Handle)obj->pendQ, (ListMP_Elem *)elem); /* Leave the gate */ GateMP_leave((GateMP_Handle)obj->gate, gateMPKey); Task_restore(tskKey);/* the calling task will switch out here */ return (TRUE); } else { obj->attrs->count--; if (obj->cacheEnabled) { Cache_wbInv(obj->attrs, sizeof(SemaphoreMP_Attrs), Cache_Type_ALL, TRUE); } /* Leave the gate */ GateMP_leave((GateMP_Handle)obj->gate, gateMPKey); return (TRUE); } }
/* * ======== Server_exec ======== */ Int Server_exec() { Int status; GateMPApp_Msg * msg; MessageQ_QueueId queId; UInt32 physAddr; volatile UInt32 * intPtr = 0; Int num = 0; Int prevNum = 0; UInt i = 0; IArg gateKey = 0; Log_print0(Diags_ENTRY | Diags_INFO, "--> Server_exec:"); /* wait for inbound message */ status = MessageQ_get(Module.slaveQue, (MessageQ_Msg *)&msg, MessageQ_FOREVER); if (status < 0) { goto leave; } if (msg->cmd != GATEMPAPP_CMD_SPTR_ADDR) { status = GATEMPAPP_E_UNEXPECTEDMSG; goto leave; } /* Get physical address of shared memory */ physAddr = msg->payload; /* translate the physical address to slave virtual addr */ if (Resource_physToVirt(physAddr, (UInt32 *)&intPtr)) { Log_error1("Server_exec: Failed to translate phys addr %p to virt addr", physAddr); goto leave; } /* send message back */ queId = MessageQ_getReplyQueue(msg); /* type-cast not needed */ msg->cmd = GATEMPAPP_CMD_SPTR_ADDR_ACK; MessageQ_put(queId, (MessageQ_Msg)msg); Log_print0(Diags_INFO,"Server_exec: Modifying shared variable " "value"); /* open host-created GateMP */ do { status = GateMP_open(GATEMP_HOST_NAME, &Module.hostGateMPHandle); } while (status == GateMP_E_NOTFOUND); if (status < 0) { Log_error0("Server_exec: Failed to open host-created GateMP"); status = GATEMPAPP_E_FAILURE; goto leave; } Log_print0(Diags_INFO,"Server_exec: Opened GateMP successfully"); Log_print0(Diags_INFO,"Server_exec: Using host-created gate"); for (i = 0;i < LOOP_ITR; i++) { /* modify the shared variable as long as no one else is currently * accessing it */ /* enter GateMP */ gateKey = GateMP_enter(Module.hostGateMPHandle); /* read shared variable value */ prevNum = *intPtr; /* randomly modify the shared variable */ if ( rand() % 2) { *intPtr -= 1; } else { *intPtr += 1; } /* read shared variable value again */ num = *intPtr; if ((prevNum != num + 1) && (prevNum != num - 1)) { Log_print0(Diags_INFO, "Server_exec: unexpected variable value." \ "Test failed."); Log_print2(Diags_INFO, "Server_exec: Previous shared variable " "value %d, current value=%d", prevNum, num); status = GATEMPAPP_E_FAILURE; goto leave; } /* leave Gate */ GateMP_leave(Module.hostGateMPHandle, gateKey); } /* wait for sync message before we switch gates */ status = MessageQ_get(Module.slaveQue, (MessageQ_Msg *)&msg, MessageQ_FOREVER); if (status < 0) { goto leave; } if (msg->cmd != GATEMPAPP_CMD_SYNC) { status = GATEMPAPP_E_UNEXPECTEDMSG; goto leave; } queId = MessageQ_getReplyQueue(msg); MessageQ_put(queId, (MessageQ_Msg)msg); Log_print0(Diags_INFO,"Server_exec: Using slave-created gate"); for (i = 0;i < LOOP_ITR; i++) { /* modify the shared variable as long as no one else is currently * accessing it */ /* enter GateMP */ gateKey = GateMP_enter(Module.slaveGateMPHandle); /* read shared variable value */ prevNum = *intPtr; /* randomly modify the shared variable */ if ( rand() % 2) { *intPtr -= 1; } else { *intPtr += 1; } /* read shared variable value again */ num = *intPtr; if ((prevNum != num - 1) && (prevNum != num + 1)) { Log_print0(Diags_INFO, "Server_exec: unexpected variable value." \ "Test failed."); Log_print2(Diags_INFO, "Server_exec: Previous " "value=%d, current value=%d", prevNum, num); status = GATEMPAPP_E_FAILURE; goto leave; } /* leave Gate */ GateMP_leave(Module.slaveGateMPHandle, gateKey); } leave: /* close host GateMP */ if (Module.hostGateMPHandle) { GateMP_close(&Module.hostGateMPHandle); } Log_print0(Diags_ENTRY, "Server_exec: host GateMP closed"); Log_print1(Diags_EXIT, "<-- Server_exec: %d", (IArg)status); return(status); }