Esempio n. 1
0
//--------------------------------------------------------------------------------------
// FUNCTION: RC_SHM_BUFFER_START
//--------------------------------------------------------------------------------------
// return (virtual) start address of off-chip shared memory
//--------------------------------------------------------------------------------------
t_vcharp RC_SHM_BUFFER_START(){
#ifdef SCC
  t_vcharp retval;
  SHMalloc(&retval); //SHMalloc() is in SCC_API.c
  return retval;
#else
  return RC_shm_buffer;
#endif
}
Esempio n. 2
0
/*++
Function:
  EventWaitOn

  Check if the event is signaled. If not signaled place
  the current thread to the list of waiting thread. This function is
  called by WaitXXXX functions when it's time to wait on a Event.
  The caller is responsible for blocking the thread, this function does
  not wait on the event.

  This function set the last error, if an error occured.

Parameters:
    IN hEvent: handle of the event checked for the signaled state.
    SHMPTR wait_state : shared memory pointer to waiting thread's wait state

returns
    WAITON_CODE value (see thread.h)
--*/
int
EventWaitOn(
    IN HANDLE hEvent, SHMPTR wait_state)
{
    Event *pEvent;
    GLOBAL_EVENT_SYSTEM_OBJECT *pEventInfo;
    int ret;
    ThreadWaitingList *pWaitingThread;
    SHMPTR shmpWaitingThread;

    pEvent = (Event *) HMGRLockHandle2(hEvent, HOBJ_EVENT);

    SHMLock();

    if ( pEvent == NULL )
    {
        SetLastError(ERROR_INVALID_HANDLE);
        ERROR("Invalid event handle %p\n", hEvent);
        SHMRelease();
        return WOC_ERROR;
    }

    pEventInfo = (GLOBAL_EVENT_SYSTEM_OBJECT*) SHMPTR_TO_PTR(pEvent->info);

    if (pEventInfo == NULL)
    {
        SetLastError(ERROR_INTERNAL_ERROR);
        ASSERT("Invalid shared memory pointer\n");
        SHMRelease();
        HMGRUnlockHandle(hEvent,&pEvent->objHeader);
        return WOC_ERROR;
    }

    if (pEventInfo->state)
    {
        DWORD *pAwakenState;

        /* try to flag the thread as awakened, don't add it to the list if it
           already was. (this happens if an object is signaled while WFMO is
           still calling WaitOn()) */
        pAwakenState = SHMPTR_TO_PTR(wait_state);

        if(!THREADInterlockedAwaken(pAwakenState,FALSE))
        {
            TRACE("thread is already awake; not waiting on it\n");
            ret = WOC_INTERUPTED;
        }
        else
        {
            TRACE("Event(%p) is signaled, not waiting\n", hEvent);
            ret = WOC_SIGNALED;

            /* reset the event, if it's not a manual reset event */
            if (pEventInfo->manualReset == FALSE)
            {
                pEventInfo->state = FALSE;
            }
        }
    }
    else
    {
        /* this structure needs to be allocated in the shared memory in
           term of supporting event for inter-process synchronization */
        /* add the current thread to the list of waiting threads */
        shmpWaitingThread = SHMalloc(sizeof(ThreadWaitingList));

        if (shmpWaitingThread == (SHMPTR) NULL)
        {
            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
            ERROR("Not enough memory to allocate a ThreadWaitingList\n");
            ret = WOC_ERROR;
        }
        else
        {
            pWaitingThread = (ThreadWaitingList *)
                             SHMPTR_TO_PTR(shmpWaitingThread);

            pWaitingThread->threadId = GetCurrentThreadId();
            pWaitingThread->processId = GetCurrentProcessId();
            pWaitingThread->blockingPipe = THREADGetPipe();
            pWaitingThread->ptr.shmNext = (SHMPTR) NULL;
            pWaitingThread->state.shmAwakened = wait_state;

            TRACE("ThreadId=%#x will wait on hEvent=%p\n",
                  pWaitingThread->threadId, hEvent);

            /* place the thread at the end of the list */
            if (pEventInfo->waitingThreads == (SHMPTR) NULL)
            {
                pEventInfo->waitingThreads = shmpWaitingThread;
            }
            else
            {
                ThreadWaitingList *pIter;
                ThreadWaitingList *pNext;

                pIter = (ThreadWaitingList *)
                        SHMPTR_TO_PTR(pEventInfo->waitingThreads);

                while (pIter && pIter->ptr.shmNext)
                {
                    pNext = (ThreadWaitingList *)
                            SHMPTR_TO_PTR(pIter->ptr.shmNext);
                    if (NULL == pNext)
                    {
                        ERROR("Invalid shared memory pointer\n");

                        /* the list is corrupted, but let's try to keep going
                           anyway with the part that's still good */
                        pIter->ptr.shmNext = 0;
                    }
                    else
                    {
                        pIter = pNext;
                    }
                }

                if(NULL == pIter)
                {
                    ERROR("Invalid shared memory pointer\n");

                    /* the list is completely corrupted... start a new one */
                    pEventInfo->waitingThreads = shmpWaitingThread;
                }
                else
                {
                    pIter->ptr.shmNext = shmpWaitingThread;
                }
            }

            TRACE("Event(%p) is not signaled,"
                  " current thread added to the waiting list\n",
                  hEvent);

            ret = WOC_WAITING;
        }
    }
    SHMRelease();
    HMGRUnlockHandle(hEvent,&pEvent->objHeader);

    return ret;
}
Esempio n. 3
0
/*++
Function:
  CreateEventW

Note:
  Events could be used for cross-process synchroniztion.
  Security Attributes could be ignored.
  lpName could be non NULL.

See MSDN doc.
--*/
HANDLE
PALAPI
CreateEventW(
    IN LPSECURITY_ATTRIBUTES lpEventAttributes,
    IN BOOL bManualReset,
    IN BOOL bInitialState,
    IN LPCWSTR lpName)
{
    HANDLE hEvent = NULL;
    Event *pEvent;
    GLOBAL_EVENT_SYSTEM_OBJECT *pEventInfo;
    SHMPTR newEvent;
    DWORD OldLastError;
    BOOL need_unlock = FALSE;
    LPCWSTR lpObjectName = NULL;
    WCHAR MangledObjectName[MAX_PATH];

    PERF_ENTRY(CreateEventW);
    ENTRY("CreateEventW(lpEventAttr=%p, bManualReset=%d, "
          "bInitialState=%d, lpName=%p (%S)\n", lpEventAttributes, bManualReset,
          bInitialState, lpName?lpName:W16_NULLSTRING, lpName?lpName:W16_NULLSTRING);

    /* Validate parameters */

    if (lpEventAttributes != NULL)
    {
        ASSERT("lpEventAttributes must be NULL\n");
        SetLastError(ERROR_INVALID_PARAMETER);
        goto CreateEventExit;
    }

    if (lpName)
    {
        lpObjectName=lpName;
        if (!MangleObjectNameW(&lpObjectName, MangledObjectName))
        {
            goto CreateEventExit;
        }

        /* take the shared memory lock to prevent other threads/processes from
           creating/deleting the object behind our back*/
        SHMLock();
        need_unlock = TRUE;

        /* Verify if there's an Event already created with that name */
        OldLastError = GetLastError();

        /* Try to open the event, using its unmangled name, as OpenEventW
               will mangle it */
        hEvent = OpenEventW(EVENT_ALL_ACCESS, FALSE, lpName);

        if (hEvent != NULL)
        {
            TRACE("Event (%S) already exist.\n", lpName);
            SetLastError(ERROR_ALREADY_EXISTS);
            goto CreateEventExit;
        }

        if (GetLastError() == ERROR_INVALID_HANDLE)
        {
            ERROR("Another kernel object is using that name\n");
            SetLastError(ERROR_INVALID_HANDLE);
            goto CreateEventExit;
        }

        SetLastError(OldLastError);
    }

    /* Allocate the event object */
    pEvent = (Event *) malloc(sizeof(Event));

    if (pEvent == NULL)
    {
        ERROR("Unable to allocate memory\n");
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        goto CreateEventExit;
    }

    /* Allocate the EventInfo in shared memory, so it can be accessible by
       other processes */

    newEvent = SHMalloc(sizeof(GLOBAL_EVENT_SYSTEM_OBJECT));

    if (newEvent == (SHMPTR) NULL)
    {
        ERROR("Unable to allocate shared memory\n");
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        free( pEvent );
        goto CreateEventExit;
    }

    pEvent->objHeader.type = HOBJ_EVENT;
    pEvent->objHeader.close_handle = CloseEventHandle;
    pEvent->objHeader.dup_handle = DupEventHandle;

    pEvent->refCount = 1;
    pEvent->info = newEvent;

    pEventInfo = (GLOBAL_EVENT_SYSTEM_OBJECT*) SHMPTR_TO_PTR(newEvent);
    pEventInfo->refCount = 1;
    pEventInfo->state = bInitialState;
    pEventInfo->manualReset = bManualReset;
    pEventInfo->waitingThreads = (SHMPTR) NULL;
    pEventInfo->next = (SHMPTR) NULL;

    pEventInfo->ShmHeader.ObjectType = SHM_NAMED_EVENTS;
    pEventInfo->ShmHeader.ShmSelf = newEvent;
    if (lpName)
    {
        if ((pEventInfo->ShmHeader.ShmObjectName = SHMWStrDup( lpObjectName )) == 0)
        {
            ERROR( "Unable to allocate shared memory!\n " );
            SetLastError(ERROR_INTERNAL_ERROR);
            SHMfree(newEvent);
            free(pEvent);
            goto CreateEventExit;
        }
    }
    else
    {
        pEventInfo->ShmHeader.ShmObjectName = 0;
    }

    hEvent = HMGRGetHandle((HOBJSTRUCT *) pEvent);

    if (hEvent == INVALID_HANDLE_VALUE)
    {
        if (lpName != NULL)
        {
            SHMfree(pEventInfo->ShmHeader.ShmObjectName);
        }
        SHMfree(newEvent);
        free(pEvent);
        ERROR("Unable to get a free handle\n");
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        goto CreateEventExit;
    }

    /* Save the EventInfo into the global link list in shared memory.
       (Only if it has a name) */
    if (lpName)
    {
        SHMAddNamedObject(newEvent);
    }

    TRACE("Event created (HANDLE=%p)\n", hEvent);

CreateEventExit:
    if(need_unlock)
    {
        /* release the lock taken before OpenEventW */
        SHMRelease();
    }
    LOGEXIT("CreateEventW returns HANDLE %p\n", hEvent);
    PERF_EXIT(CreateEventW);
    return hEvent;
}