/* * ======== Notify_eventAvailable ======== */ Bool Notify_eventAvailable(UInt16 procId, UInt16 lineId, UInt32 eventId) { UInt32 strippedEventId = (eventId & 0xFFFF); UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(procId); Bool available; ti_sdo_ipc_Notify_Object *obj; 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); obj = (ti_sdo_ipc_Notify_Object *) Notify_module->notifyHandles[clusterId][lineId]; if (obj == NULL) { /* Driver not registered */ return (FALSE); } if (!ISRESERVED(eventId)) { /* Event is reserved and the caller isn't using Notify_SYSTEMKEY */ return (FALSE); } available = (obj->callbacks[strippedEventId].fnNotifyCbck == NULL); return (available); }
/* * ======== Notify_enableEvent ======== */ Void Notify_enableEvent(UInt16 procId, UInt16 lineId, UInt32 eventId) { UInt32 strippedEventId = (eventId & 0xFFFF); UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(procId); ti_sdo_ipc_Notify_Object *obj; UInt sysKey; 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); obj = (ti_sdo_ipc_Notify_Object *) Notify_module->notifyHandles[clusterId][lineId]; Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered); if (procId != MultiProc_self()) { /* enable the remote event */ INotifyDriver_enableEvent(obj->driverHandle, strippedEventId); } else { /* enable the local event */ sysKey = Hwi_disable(); SET_BIT(Notify_module->localEnableMask, strippedEventId); Hwi_restore(sysKey); } }
static void _export_token (Token t) { static Token lasttok; static bool concatenation = false; if (t == FINISH_CMD) { if (lasttok) output_itoken (GLOBAL, lasttok); } else if (t == CONCAT_CMD) { if (concatenation) return; if (!lasttok) return; concatenation = true; } else if (!ISSYMBOL (t) && !ISRESERVED (t) && !ISVALUE (t)) { if (lasttok) output_itoken (GLOBAL, lasttok); output_itoken (GLOBAL, t); lasttok = 0; concatenation = false; } else if (!concatenation) { if (lasttok) output_itoken (GLOBAL, lasttok); lasttok = t; } else { char *tmp = (char*) alloca (strlen (expand (lasttok)) + strlen (expand (t)) + 1); strcat (strcpy (tmp, expand (lasttok)), expand (t)); lasttok = new_symbol (strdup (tmp)); } }
/* * ======== Notify_unregisterEventSingle ======== */ Int Notify_unregisterEventSingle(UInt16 procId, UInt16 lineId, UInt32 eventId) { UInt32 strippedEventId = (eventId & 0xFFFF); UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(procId); Int status; ti_sdo_ipc_Notify_Object *obj; UInt modKey; 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); modKey = Gate_enterModule(); obj = (ti_sdo_ipc_Notify_Object *) Notify_module->notifyHandles[clusterId][lineId]; Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered); if (obj->callbacks[strippedEventId].fnNotifyCbck) { if (procId != MultiProc_self()) { /* * First, Tell the remote notify driver that the event is now * unregistered */ INotifyDriver_unregisterEvent(obj->driverHandle, strippedEventId); } /* * No need to protect these modifications with the system gate because * we shouldn't get preempted by Notify_exec after INotifyDriver_ * unregisterEvent. */ obj->callbacks[strippedEventId].fnNotifyCbck = NULL; obj->callbacks[strippedEventId].cbckArg = NULL; status = Notify_S_SUCCESS; } else { /* No callback is registered. Fail. */ status = Notify_E_FAIL; } Gate_leaveModule(modKey); return (status); }
/* * ======== Notify_registerEventSingle ======== */ Int Notify_registerEventSingle(UInt16 procId, UInt16 lineId, UInt32 eventId, Notify_FnNotifyCbck fnNotifyCbck, UArg cbckArg) { UInt32 strippedEventId = (eventId & 0xFFFF); UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(procId); UInt modKey; Int status; ti_sdo_ipc_Notify_Object *obj; 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); modKey = Gate_enterModule(); obj = (ti_sdo_ipc_Notify_Object *) Notify_module->notifyHandles[clusterId][lineId]; Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered); if (obj->callbacks[strippedEventId].fnNotifyCbck) { /* A callback is already registered. Fail. */ status = Notify_E_ALREADYEXISTS; } else { /* * No callback is registered. Register it. There is no need to protect * these modifications because the event isn't registered yet. */ obj->callbacks[strippedEventId].fnNotifyCbck = (Fxn)fnNotifyCbck; obj->callbacks[strippedEventId].cbckArg = cbckArg; if (procId != MultiProc_self()) { /* Tell the remote notify driver that the event is now registered */ INotifyDriver_registerEvent(obj->driverHandle, strippedEventId); } status = Notify_S_SUCCESS; } Gate_leaveModule(modKey); return (status); }
/* * ======== Notify_unregisterEvent ======== */ Int Notify_unregisterEvent(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; UInt sysKey, modKey; ti_sdo_ipc_Notify_Object *obj; List_Handle eventList; ti_sdo_ipc_Notify_EventListener *listener; UInt count = 0; 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); modKey = Gate_enterModule(); obj = (ti_sdo_ipc_Notify_Object *) Notify_module->notifyHandles[clusterId][lineId]; Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered); eventList = List_Object_get(obj->eventList, strippedEventId); if (List_empty(eventList)) { return (Notify_E_NOTFOUND); } /* Get the first listener on the list */ listener = (ti_sdo_ipc_Notify_EventListener *)List_next(eventList, NULL); while (listener != NULL) { count++; if (listener->callback.fnNotifyCbck == (Fxn)fnNotifyCbck && listener->callback.cbckArg == cbckArg ) { break; /* found a match! */ } listener = (ti_sdo_ipc_Notify_EventListener *) List_next(eventList, (List_Elem *)listener); } if (listener == NULL) { /* Event listener not found */ status = Notify_E_NOTFOUND; } else { if (count == 1 && List_next(eventList, (List_Elem *)listener) == NULL) { /* * If only one element counted so far and the List_next returns * NULL, the list will be empty after unregistering. Therefore, * unregister the callback function. */ status = Notify_unregisterEventSingle(procId, lineId, eventId); /* unregisterEvent should always suceed */ Assert_isTrue(status == Notify_S_SUCCESS, ti_sdo_ipc_Notify_A_internal); /* No need to protect the list removal: the event's unregistered */ List_remove(eventList, (List_Elem *)listener); } else { /* * Need to atomically remove from the list using the system gate * because Notify_exec might preempt List_remove (the event is * still registered) */ sysKey = Hwi_disable(); List_remove(eventList, (List_Elem *)listener); Hwi_restore(sysKey); } /* Free the memory alloc'ed for the event listener */ Memory_free(ti_sdo_ipc_Notify_Object_heap(), listener, sizeof(ti_sdo_ipc_Notify_EventListener)); status = Notify_S_SUCCESS; } Gate_leaveModule(modKey); return (status); }
/* * ======== Notify_sendEvent ======== */ Int Notify_sendEvent(UInt16 procId, UInt16 lineId, UInt32 eventId, UInt32 payload, Bool waitClear) { UInt32 strippedEventId = (eventId & 0xFFFF); UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(procId); Int status; ti_sdo_ipc_Notify_Object *obj; UInt sysKey; 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); obj = (ti_sdo_ipc_Notify_Object *) Notify_module->notifyHandles[clusterId][lineId]; Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered); if (procId != MultiProc_self()) { /* Send a remote event */ status = INotifyDriver_sendEvent(obj->driverHandle, strippedEventId, payload, waitClear); } else { /* * The check agaist non-NULL fnNotifyCbCk must be atomic with * Notify_exec so Notify_exec doesn't encounter a null callback. */ sysKey = Hwi_disable(); /* * If nesting == 0 (the driver is enabled) and the event is enabled, * send the event */ if (obj->callbacks[strippedEventId].fnNotifyCbck == NULL) { /* No callbacks are registered locally for the event. */ status = Notify_E_EVTNOTREGISTERED; } else if (obj->nesting != 0) { /* Driver is disabled */ status = Notify_E_FAIL; } else if (!TEST_BIT (Notify_module->localEnableMask, strippedEventId)) { /* Event is disabled */ status = Notify_E_EVTDISABLED; } else { /* Execute the callback function registered to the event */ ti_sdo_ipc_Notify_exec(obj, strippedEventId, payload); status = Notify_S_SUCCESS; } Hwi_restore(sysKey); } return (status); }
/* * ======== 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); }