/* * ======== NullConverter_issue ======== */ Void NullConverter_issue(NullConverter_Object *obj, DriverTypes_Packet *packet, Error_Block *eb) { List_put(NullConverter_Instance_State_packetList(obj), (List_Elem *)packet); obj->cbFxn(obj->cbArg); }
/*! * @brief Insert an entry into the Translation Table * * @param da Device address * @param ua User address * @param size Buffer size * * @sa _SysLinkMemUtils_removeMapElement */ static Int32 _SysLinkMemUtils_insertMapElement (Ptr da, Ptr ua, UInt32 size) { AddrNode * node; Int32 status = PROCMGR_SUCCESS; GT_3trace (curTrace, GT_ENTER, "_SysLinkMemUtils_insertMapElement", da, ua, size); node = Memory_alloc (NULL, sizeof (AddrNode), 0); if (!node) { status = PROCMGR_E_MEMORY; #if !defined(SYSLINK_BUILD_OPTIMIZE) GT_setFailureReason (curTrace, GT_4CLASS, (Char *)__func__, status, "Error allocating node memory!"); #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */ } else { node->ua = ua; node->da = da; node->size = size; OsalSemaphore_pend (SysLinkMemUtils_module->semList, OSALSEMAPHORE_WAIT_FOREVER); List_put (SysLinkMemUtils_module->addrTable, &node->elem); OsalSemaphore_post (SysLinkMemUtils_module->semList); } GT_1trace (curTrace, GT_LEAVE, "_SysLinkMemUtils_insertMapElement", status); return status; }
/* * ======== Stream_postInit ======== */ Int Stream_postInit(Stream_Object *obj, Error_Block *eb) { List_Handle freeList; UInt i, len; IDriver_Handle drvHandle; DriverAdapter_Params adapPrms; freeList = Stream_Instance_State_freeList(obj); /* * Split the buffer into packets and add to freeList */ for (i = 0; i < obj->maxIssues; i++) { List_put(freeList, (List_Elem *)&obj->packets[i]); } len = Stream_match(obj->name, &obj->convHandle, eb); if (len == 0) { /* Look in DriverTable */ obj->drvAdapHdl = TRUE; len = DriverTable_match(obj->name, &drvHandle, eb); if (len == 0) { /* The name was not found */ Error_raise(eb, Stream_E_notFound, obj->name, 0); return (3); } else { DriverAdapter_Params_init(&adapPrms); adapPrms.driverHandle = drvHandle; obj->convHandle = DriverAdapter_Handle_upCast( DriverAdapter_create(&adapPrms, eb)); if (obj->convHandle == NULL) { return (4); } } } else { obj->drvAdapHdl = FALSE; } IConverter_open(obj->convHandle, ((obj->name) + len), obj->mode, obj->chanParams, Stream_internalCallback, (UArg)obj, eb); if (Error_check(eb)) { return (5); } return (0); }
/* * ======== DriverAdapter_callback ======== * This function is called by the driver when I/O completes. */ Void DriverAdapter_callback(UArg cbArg, DriverTypes_Packet *packet) { DriverAdapter_Object *obj = (DriverAdapter_Object *)cbArg; List_Handle fromDriver; Stream_completedLog((UArg)packet->addr, (UArg)packet->size, (UArg)packet->arg); fromDriver = DriverAdapter_Instance_State_fromDriver(obj); /* put packet in fromDriver queue for collection by reclaim */ List_put(fromDriver, (List_Elem *)packet); /* callback into top layer */ obj->cbFxn(obj->cbArg); }
/* * ======== Notify_registerEvent ======== */ Int Notify_registerEvent(UInt16 procId, UInt16 lineId, UInt32 eventId, Notify_FnNotifyCbck fnNotifyCbck, UArg cbckArg) { UInt32 strippedEventId = (eventId & 0xFFFF); UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(procId); Int status; ti_sdo_ipc_Notify_Object *obj; UInt modKey; List_Handle eventList; ti_sdo_ipc_Notify_EventListener *listener; Bool listWasEmpty; Error_Block eb; Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors && lineId < ti_sdo_ipc_Notify_numLines, ti_sdo_ipc_Notify_A_invArgument); Assert_isTrue(strippedEventId < ti_sdo_ipc_Notify_numEvents, ti_sdo_ipc_Notify_A_invArgument); Assert_isTrue(ISRESERVED(eventId), ti_sdo_ipc_Notify_A_reservedEvent); Error_init(&eb); modKey = Gate_enterModule(); obj = (ti_sdo_ipc_Notify_Object *) Notify_module->notifyHandles[clusterId][lineId]; Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered); /* Allocate a new EventListener */ listener = Memory_alloc(ti_sdo_ipc_Notify_Object_heap(), sizeof(ti_sdo_ipc_Notify_EventListener), 0, &eb); if (listener == NULL) { /* Listener memory allocation failed. Leave module gate & return */ Gate_leaveModule(modKey); return (Notify_E_MEMORY); } listener->callback.fnNotifyCbck = (Fxn)fnNotifyCbck; listener->callback.cbckArg = cbckArg; eventList = List_Object_get(obj->eventList, strippedEventId); /* * Store whether the list was empty so we know whether to register the * callback */ listWasEmpty = List_empty(eventList); /* * Need to atomically add to the list using the system gate because * Notify_exec might preempt List_remove. List_put is atomic. */ List_put(eventList, (List_Elem *)listener); if (listWasEmpty) { /* * Registering this event for the first time. Need to register the * callback function. */ status = Notify_registerEventSingle(procId, lineId, eventId, Notify_execMany, (UArg)obj); /* Notify_registerEventSingle should always succeed */ Assert_isTrue(status == Notify_S_SUCCESS, ti_sdo_ipc_Notify_A_internal); } status = Notify_S_SUCCESS; Gate_leaveModule(modKey); return (status); }
/* * ======== Stream_reclaim ======== */ SizeT Stream_reclaim(Stream_Object *obj, Ptr *bufp, UInt timeout, UArg *arg, Error_Block *eb) { DriverTypes_Packet *packet = NULL; List_Handle freeList; UInt key; if (obj->issued == 0) { Error_raise(eb, Stream_E_noBuffersIssued, 0, 0); return (0); } while (obj->ready == 0) { if (!Sync_wait(obj->complete, timeout, eb)) { if (timeout != 0) { Error_raise(eb, Stream_E_timeout, timeout, 0); } return (0); } }; IConverter_reclaim(obj->convHandle, &packet, eb); if (arg != NULL) { *arg = packet->arg; } /* bufp is NULL in Stream_read and Stream_write. */ if (bufp != NULL) { *bufp = packet->addr; } key = Hwi_disable(); obj->ready--; Hwi_restore(key); obj->issued--; /* * re-signal if more buffers are ready * This is required in the case of ISyncEvent and ISyncSwi to allow * clients to reclaim a single buffer and not force them to bleed the * Stream. In the case of ISyncSem , this re-signal is an overhead */ if (obj->ready > 0) { Sync_signal(obj->complete); } freeList = Stream_Instance_State_freeList(obj); /* recycle packet back onto free list */ List_put(freeList, (List_Elem *)packet); if ((packet->error != NULL) && (packet->error != DriverTypes_EABORTED)) { Error_raise(eb, packet->error, packet->status, 0); return (0); } else { return (packet->size); } }
/* * ======== MessageQ_put ======== */ Int MessageQ_put(MessageQ_QueueId queueId, MessageQ_Msg msg) { IMessageQTransport_Handle transport; MessageQ_QueueIndex dstProcId = (MessageQ_QueueIndex)(queueId >> 16); List_Handle listHandle; Int status; UInt priority; #ifndef xdc_runtime_Log_DISABLE_ALL UInt16 flags; UInt16 seqNum; UInt16 srcProc; #endif ti_sdo_ipc_MessageQ_Object *obj; Assert_isTrue((msg != NULL), ti_sdo_ipc_MessageQ_A_invalidMsg); msg->dstId = (UInt16)(queueId); msg->dstProc = (UInt16)(queueId >> 16); if (dstProcId != MultiProc_self()) { /* assert that dstProcId is valid */ Assert_isTrue(dstProcId < ti_sdo_utils_MultiProc_numProcessors, ti_sdo_ipc_MessageQ_A_procIdInvalid); /* Put the high and urgent messages to the high priority transport */ priority = (UInt)((msg->flags) & ti_sdo_ipc_MessageQ_TRANSPORTPRIORITYMASK); /* Call the transport associated with this message queue */ transport = MessageQ_module->transports[dstProcId][priority]; if (transport == NULL) { /* Try the other transport */ priority = !priority; transport = MessageQ_module->transports[dstProcId][priority]; } /* assert transport is not null */ Assert_isTrue(transport != NULL, ti_sdo_ipc_MessageQ_A_unregisteredTransport); #ifndef xdc_runtime_Log_DISABLE_ALL /* use local vars so msg does not get cached after put */ flags = msg->flags; if ((ti_sdo_ipc_MessageQ_traceFlag) || (flags & ti_sdo_ipc_MessageQ_TRACEMASK) != 0) { /* use local vars so msg does not get cached after put */ seqNum = msg->seqNum; srcProc = msg->srcProc; } #endif /* put msg to remote processor using transport */ if (IMessageQTransport_put(transport, msg)) { status = MessageQ_S_SUCCESS; #ifndef xdc_runtime_Log_DISABLE_ALL /* if trace enabled */ if ((ti_sdo_ipc_MessageQ_traceFlag) || (flags & ti_sdo_ipc_MessageQ_TRACEMASK) != 0) { Log_write4(ti_sdo_ipc_MessageQ_LM_putRemote, (UArg)(msg), (UArg)(seqNum), (UArg)(srcProc), (UArg)(dstProcId)); } #endif } else { status = MessageQ_E_FAIL; } } else { /* Assert queueId is valid */ Assert_isTrue((UInt16)queueId < MessageQ_module->numQueues, ti_sdo_ipc_MessageQ_A_invalidQueueId); /* It is a local MessageQ */ obj = MessageQ_module->queues[(UInt16)(queueId)]; /* Assert object is not NULL */ Assert_isTrue(obj != NULL, ti_sdo_ipc_MessageQ_A_invalidObj); if ((msg->flags & MessageQ_PRIORITYMASK) == MessageQ_URGENTPRI) { listHandle = ti_sdo_ipc_MessageQ_Instance_State_highList(obj); List_putHead(listHandle, (List_Elem *)msg); } else { if ((msg->flags & MessageQ_PRIORITYMASK) == MessageQ_NORMALPRI) { listHandle = ti_sdo_ipc_MessageQ_Instance_State_normalList(obj); } else { listHandle = ti_sdo_ipc_MessageQ_Instance_State_highList(obj); } /* put on the queue */ List_put(listHandle, (List_Elem *)msg); } ISync_signal(obj->synchronizer); status = MessageQ_S_SUCCESS; if ((ti_sdo_ipc_MessageQ_traceFlag) || (msg->flags & ti_sdo_ipc_MessageQ_TRACEMASK) != 0) { Log_write4(ti_sdo_ipc_MessageQ_LM_putLocal, (UArg)(msg), (UArg)(msg->seqNum), (UArg)(msg->srcProc), (UArg)(obj)); } } return (status); }
Void ListTest(Void) { List_Params listParams; List_Handle listHandle; List_Elem *elem; ListNode *node; UInt32 i, value; Bool failed = FALSE; IGateProvider_Handle gateHandle; List_Params_init(&listParams); gateHandle = (IGateProvider_Handle) GateMutex_create(); if(gateHandle == NULL) { Osal_printf("ListTest: GateMutex_create failed.\n"); goto exit; } listParams.gateHandle = gateHandle; listHandle = List_create(&listParams); if(listHandle == NULL) { Osal_printf("ListTest: List_create failed.\n"); goto gateExit; } node = Memory_alloc(NULL, LIST_SIZE * sizeof(ListNode), 0); if(node == NULL) { Osal_printf("ListTest: Memory_alloc failed.\n"); goto listExit; } // Put some nodes into the list for(i = 0; i < LIST_SIZE; i++) { node[i].value = i; List_put(listHandle, (List_Elem *)&node[i]); } // Traverse the list for(i = 0, elem = List_next(listHandle, NULL); elem != NULL && !failed; i++, elem = List_next(listHandle, elem)) { value = ((ListNode *)elem)->value; // Check against expected value if(value != i) { Osal_printf("ListTest: data mismatch, expected " "0x%x, actual 0x%x\n", i, i, value); failed = TRUE; } } // Remove nodes for(i = 0; i < LIST_SIZE && !List_empty(listHandle); i++) { // Get first element and put it back to test List_get and List_putHead elem = List_get(listHandle); List_putHead(listHandle, elem); // Now remove it permanently to test List_remove if(elem != NULL) { List_remove(listHandle, elem); } } // Did we remove the expected number of nodes? if(i != LIST_SIZE) { Osal_printf("ListTest: removed %d node(s), expected %d\n", i, LIST_SIZE); failed = TRUE; } if(!List_empty(listHandle)) { Osal_printf("ListTest: list not empty!\n"); failed = TRUE; } if(failed) Osal_printf("ListTest: FAILED!\n"); else Osal_printf("ListTest: PASSED!\n"); listExit: List_delete(&listHandle); gateExit: GateMutex_delete((GateMutex_Handle *)&gateHandle); exit: return; }
Int RcmClient_getReturnMsg_P(RcmClient_Object *obj, const UInt16 msgId, RcmClient_Message **returnMsg) { List_Elem *elem; Recipient *recipient; RcmClient_Packet *packet; Bool messageDelivered; MessageQ_Msg msgqMsg = NULL; Bool messageFound = FALSE; Int queueLockAcquired = 0; Error_Block eb; Int rval; Int status = RcmClient_S_SUCCESS; Log_print3(Diags_ENTRY, "--> "FXNN": (obj=0x%x, msgId=%d, returnMsgPtr=0x%x", (IArg)obj, (IArg)msgId, (IArg)returnMsg); Error_init(&eb); *returnMsg = NULL; /* keep trying until message found */ while (!messageFound) { /* acquire the mailbox lock */ Semaphore_pend(obj->mbxLock, Semaphore_FOREVER, &eb); if (Error_check(&eb)) { /* TODO */ goto leave; } /* search new mail list for message */ elem = NULL; while ((elem = List_next(obj->newMail, elem)) != NULL) { packet = getPacketAddrElem(elem); if (msgId == packet->msgId) { List_remove(obj->newMail, elem); *returnMsg = &packet->message; messageFound = TRUE; break; } } if (messageFound) { /* release the mailbox lock */ Semaphore_post(obj->mbxLock, &eb); if (Error_check(&eb)) { /* TODO */ } } else { /* attempt the message queue lock */ queueLockAcquired = Semaphore_pend(obj->queueLock, 0, &eb); if (Error_check(&eb)) { /* TODO */ goto leave; } if (1 == queueLockAcquired) { /* * mailman role */ /* deliver new mail until message found */ while (!messageFound) { /* get message from queue if available (non-blocking) */ if (NULL == msgqMsg) { rval = MessageQ_get(obj->msgQue, &msgqMsg, 0); if ((MessageQ_E_TIMEOUT != rval) && (rval < 0)) { Log_error0(FXNN": lost return message"); status = RcmClient_E_LOSTMSG; goto leave; } Log_print0(Diags_INFO, FXNN": return message received"); } while (NULL != msgqMsg) { /* check if message found */ packet = getPacketAddrMsgqMsg(msgqMsg); messageFound = (msgId == packet->msgId); if (messageFound) { *returnMsg = &packet->message; /* search wait list for new mailman */ elem = NULL; while ((elem = List_next(obj->recipients, elem)) != NULL) { recipient = (Recipient *)elem; if (NULL == recipient->msg) { /* signal recipient's event */ SemThread_post(SemThread_handle( &recipient->event), &eb); break; } } /* release the message queue lock */ Semaphore_post(obj->queueLock, &eb); if (Error_check(&eb)) { /* TODO */ } /* release the mailbox lock */ Semaphore_post(obj->mbxLock, &eb); if (Error_check(&eb)) { /* TODO */ } break; } else { /* * deliver message to mailbox */ /* search recipient list for message owner */ elem = NULL; messageDelivered = FALSE; while ((elem = List_next(obj->recipients, elem)) != NULL) { recipient = (Recipient *)elem; if (recipient->msgId == packet->msgId) { recipient->msg = &packet->message; /* signal the recipient's event */ SemThread_post(SemThread_handle( &recipient->event), &eb); messageDelivered = TRUE; break; } } /* add undelivered message to new mail list */ if (!messageDelivered) { /* use the elem in the MessageQ header */ elem = (List_Elem *)&packet->msgqHeader; List_put(obj->newMail, elem); } } /* get next message from queue if available */ rval = MessageQ_get(obj->msgQue, &msgqMsg, 0); if ((MessageQ_E_TIMEOUT != rval) && (rval < 0)) { Log_error0(FXNN": lost return message"); status = RcmClient_E_LOSTMSG; goto leave; } Log_print0(Diags_INFO, FXNN": return message received"); } if (!messageFound) { /* * message queue empty */ /* release the mailbox lock */ Semaphore_post(obj->mbxLock, &eb); if (Error_check(&eb)) { /* TODO */ } /* get next message, this blocks the thread */ rval = MessageQ_get(obj->msgQue, &msgqMsg, MessageQ_FOREVER); if (rval < 0) { Log_error0(FXNN": lost return message"); status = RcmClient_E_LOSTMSG; goto leave; } Log_print0(Diags_INFO, FXNN": return message received"); if (msgqMsg == NULL) { Log_error0(FXNN": reply message has been lost"); status = RcmClient_E_LOSTMSG; goto leave; } /* acquire the mailbox lock */ Semaphore_pend(obj->mbxLock, Semaphore_FOREVER, &eb); if (Error_check(&eb)) { goto leave; /* TODO */ } } } } else { /* construct recipient on local stack */ Recipient self; self.msgId = msgId; self.msg = NULL; SemThread_construct(&self.event, 0, NULL, &eb); if (Error_check(&eb)) { /* TODO */ } /* add recipient to wait list */ elem = &self.elem; List_put(obj->recipients, elem); /* release the mailbox lock */ Semaphore_post(obj->mbxLock, &eb); if (Error_check(&eb)) { /* TODO */ } /* wait on event */ SemThread_pend(SemThread_handle(&self.event), Semaphore_FOREVER, &eb); if (Error_check(&eb)) { /* TODO */ } /* acquire the mailbox lock */ Semaphore_pend(obj->mbxLock, Semaphore_FOREVER, &eb); if (Error_check(&eb)) { goto leave; /* TODO */ } if (NULL != self.msg) { /* pickup message */ *returnMsg = self.msg; messageFound = TRUE; } /* remove recipient from wait list */ List_remove(obj->recipients, elem); SemThread_destruct(&self.event); /* release the mailbox lock */ Semaphore_post(obj->mbxLock, &eb); if (Error_check(&eb)) { /* TODO */ } } } } /* while (!messageFound) */ leave: Log_print2(Diags_EXIT, "<-- %s: %d", (IArg)FXNN, (IArg)status); return(status); }