Esempio n. 1
0
/* This code forms a small cache of pre-allocated blocks that can be allocated by
 * the host without using (comparitively slow) spinlocks and semaphores. additionally
 * block coalescing does not take place which saves a number of uncached reads
 */
static void *allocBuffer(RemoteTransformer_t *remoteTransformer, MME_UINT sz)
{
	EMBX_ERROR err;
	EMBX_VOID *ptr;

	if (sz <= 4096) {
		EMBX_OS_INTERRUPT_LOCK();		

		if (remoteTransformer->bufferCache) {
			ptr = remoteTransformer->bufferCache;
			remoteTransformer->bufferCache = *remoteTransformer->bufferCache;

			EMBX_OS_INTERRUPT_UNLOCK();

			/* this assert technically has side effects (alters sz) so have a
			 * care if altering this function
			 */
			MME_Assert(EMBX_SUCCESS == EMBX_GetBufferSize(ptr, &sz));
			MME_Assert(4096 == sz);
			return ptr;
		}

		sz = 4096;
		EMBX_OS_INTERRUPT_UNLOCK();
	}
	err = EMBX_Alloc(remoteTransformer->super.info->handle, sz, &ptr);

	return (EMBX_SUCCESS == err ? ptr : 0);
}
Esempio n. 2
0
void send_thread(void *param)
{
EMBX_PORT port = (EMBX_PORT)param;
EMBX_ERROR res;
EMBX_VOID *buffer;

    EMBX_OS_Delay(5000);

    EMBX_Alloc(tp,BUFFER_SIZE,&buffer);

    res = EMBX_SendMessage(port,buffer,BUFFER_SIZE);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("port_thread failed, res = %s\n",error_strings[res]));
        return;
    }
}
Esempio n. 3
0
/* Construct a one-way message requesting complete termination of our partner CPU. */
static MME_ERROR createTerminateMMEMessage(TransportInfo_t *tpInfo,
					   TransformerTerminateMMEMessage** buffer) {
	TransformerTerminateMMEMessage *message;
	EMBX_ERROR err;

	MME_Assert(manager);
	MME_Assert(tpInfo);
	MME_Assert(buffer);
	
	err = EMBX_Alloc(tpInfo->handle, sizeof(*message), (EMBX_VOID **) &message);
	if (EMBX_SUCCESS == err) {
		message->id = TMESSID_TERMINATE_MME;
		message->messageSize = sizeof(*message);
		message->result = MME_SUCCESS;
		*buffer = message;
	}
	
	/* map the EMBX error to an MME one */
	return EMBX_SUCCESS == err ? MME_SUCCESS :
	       EMBX_NOMEM == err   ? MME_NOMEM :
	                             MME_EMBX_ERROR;
}
Esempio n. 4
0
/* Construct a two-way message to determine if the named transformer can be
 * instanciated by (has been registered on) a particular companion processor.
 */
static MME_ERROR createRegisteredMessage(TransportInfo_t *tpInfo, const char *name,
					 TransformerRegisteredMessage **msg)
{
	EMBX_ERROR err;
	void *buf;

	err = EMBX_Alloc(tpInfo->handle, sizeof(TransformerRegisteredMessage), &buf);
	if (EMBX_SUCCESS != err) {
		return EMBX_NOMEM == err ? MME_NOMEM : MME_EMBX_ERROR;
	}

	*msg = buf;
	(*msg)->id = TMESSID_TRANSFORMER_REGISTERED;
	(*msg)->messageSize = sizeof(TransformerRegisteredMessage);
	(*msg)->result = MME_UNKNOWN_TRANSFORMER;
	
	/* MULTIHOST support */
	strcpy((*msg)->portName, tpInfo->replyPortName);
	strcpy((*msg)->transformerType, name);

	return MME_SUCCESS;
}
Esempio n. 5
0
int main()
{
EMBX_TRANSPORT hTrans;
EMBX_PORT bufferpool, consumer, mypoolconnection;
EMBX_ERROR err;
int i;

	embxRuntimeInit();
	err = EMBX_OpenTransport("shm", &hTrans);
	assert(EMBX_SUCCESS == err);

	/* Create the port which will hold the pool of work buffers */
	err = EMBX_CreatePort(hTrans, "bufferpool", &bufferpool);
	assert(EMBX_SUCCESS == err);

	/* Make a connection to the port we just created so we can inject
	 * empty buffers onto the port's queue as part of the initialization
	 */
	err = EMBX_Connect(hTrans, "bufferpool", &mypoolconnection);
	assert(EMBX_SUCCESS == err);

	/* Now wait for the consumer port to come into existence and 
	 * make a connection to it.
	 */
	err = EMBX_ConnectBlock(hTrans, "consumer", &consumer);
	assert(EMBX_SUCCESS == err);


	/* Inject empty buffers into the buffer pool */
	for(i=0;i<BUFFER_POOL_SIZE;i++)
	{
	EMBX_VOID *buffer;
		
		err = EMBX_Alloc(hTrans, BUFFER_SIZE, &buffer);
		assert(EMBX_SUCCESS == err);

		/* Send empty buffer to the buffer pool port */
		err = EMBX_SendMessage(mypoolconnection, buffer, 0);
		assert(EMBX_SUCCESS == err);
	}

	/* We don't need our connection to the buffer pool anymore
	 * so close it down.
	 */
	EMBX_ClosePort(mypoolconnection);

	for(i=0;i<100;i++)
	{
	EMBX_RECEIVE_EVENT ev;
	EMBX_UINT buffersize;
		
		/* Jabber ... */
		printf("producer: Issuing message %d of 100\n", i+1);


		/* Get an empty buffer from the pool */
		err = EMBX_ReceiveBlock(bufferpool, &ev);
		assert(EMBX_SUCCESS == err);

		/* The event size field does not represent the actual
		 * size of the buffer in this case, hence if you need
		 * to find that out use the following. However in this
		 * case where all the buffers are the same known size 
		 * it wouldn't be necessary expect as self checking debug.
		 */
		err = EMBX_GetBufferSize(ev.data, &buffersize);
		assert(EMBX_SUCCESS == err);

		/* Do something to fill the buffer with stuff to be used
		 * by the consumer...... use your imagination ......
		 */


		/* Now send the buffer to the consumer with the real amount
		 * of data in the buffer as the size argument (this can be
		 * less than the buffer size). For this example we assume
		 * the whole buffer contains valid data.
		 */
		err = EMBX_SendMessage(consumer, ev.data, buffersize);
		assert(EMBX_SUCCESS == err);
	}

	/* Shut the communication system down. This has the side effect
	 * of causing the consumer to also close down, almost certainly
	 * before outstanding messages have been processed.
	 */
	EMBX_ClosePort(bufferpool);
	EMBX_ClosePort(consumer);
	EMBX_CloseTransport(hTrans);
	EMBX_Deinit();

	return 0;
}
int run_test(void)
{
EMBX_ERROR     res;
EMBX_TPINFO    tpinfo1;
EMBX_BOOL      bFailed;
EMBX_TRANSPORT tp;
EMBX_PORT      localPort,remotePort;
EMBX_VOID     *buffer1,*buffer2;
EMBX_FACTORY   factory;

    bFailed = EMBX_FALSE;
    tp      = EMBX_INVALID_HANDLE_VALUE;
    buffer1 = buffer2 = 0;

    /* Test 1 */
    res = EMBX_SendMessage(EMBX_INVALID_HANDLE_VALUE, buffer1, 0);
    if(res != EMBX_INVALID_PORT)
    {
        EMBX_Info(EMBX_TRUE, ("Test1 failed, res = %s\n",error_strings[res]));
        bFailed = EMBX_TRUE;
    }

    res = EMBX_RegisterTransport(EMBXLB_loopback_factory,&loopback_config,sizeof(EMBXLB_Config_t),&factory);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Transport Registration failed, res = %s, exiting\n",error_strings[res]));
        goto skip_remaining_tests;
    }

    /* Test 2 */
    res = EMBX_Init();
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test2 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }

    /* Test 3 */
    res = EMBX_GetFirstTransport(&tpinfo1);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test3 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }

    /* Test 4 */
    res = EMBX_OpenTransport(tpinfo1.name, &tp);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test4 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }

    /* Test 5 */
    res = EMBX_CreatePort(tp, "testport", &localPort);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test5 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }
    
    /* Test 6 */
    res = EMBX_Connect(tp, "testport", &remotePort);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test6 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }
    
    /* Test 7 */
    res = EMBX_Alloc(tp, BUFFER_SIZE, &buffer1);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test7 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }

    /* Test 8 */
    res = EMBX_SendMessage(tp, buffer1, 0);
    if(res != EMBX_INVALID_PORT)
    {
        EMBX_Info(EMBX_TRUE, ("Test8 failed, res = %s\n",error_strings[res]));
        bFailed = EMBX_TRUE;
    }

    /* Test 9 */
    res = EMBX_SendMessage(localPort, buffer1, 0);
    if(res != EMBX_INVALID_PORT)
    {
        EMBX_Info(EMBX_TRUE, ("Test9 failed, res = %s\n",error_strings[res]));
        bFailed = EMBX_TRUE;
    }

    /* Test 10 */
    res = EMBX_SendMessage(remotePort, 0, 0);
    if(res != EMBX_INVALID_ARGUMENT)
    {
        EMBX_Info(EMBX_TRUE, ("Test10 failed, res = %s\n",error_strings[res]));
        bFailed = EMBX_TRUE;
    }

    /* Test 11 */
    res = EMBX_SendMessage(remotePort, buffer1, BUFFER_SIZE+1);
    if(res != EMBX_INVALID_ARGUMENT)
    {
        EMBX_Info(EMBX_TRUE, ("Test11 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }

    /* Test 12 */
    res = EMBX_SendMessage(remotePort, buffer1, BUFFER_SIZE);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test12 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }

    /* Test 13 - Ensure this allocation happens before buffer1 gets free'd
     * when the port is closed, so buffer1 and buffer2 will not point to
     * the same memory which is important for later tests.
     */
    res = EMBX_Alloc(tp, BUFFER_SIZE, &buffer2);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test13 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }

    /* Test 14 */
    res = EMBX_ClosePort(localPort);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test14 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }

    /* Test 15 - buffer1 has been freed by test14 so should be garbage */
    res = EMBX_SendMessage(remotePort, buffer1, 0);
    if(res != EMBX_INVALID_ARGUMENT)
    {
        EMBX_Info(EMBX_TRUE, ("Test15 failed, res = %s\n",error_strings[res]));
        bFailed = EMBX_TRUE;
    }

    /* Test 16 */
    res = EMBX_SendMessage(remotePort, buffer2, BUFFER_SIZE);
    if(res != EMBX_INVALID_PORT)
    {
        EMBX_Info(EMBX_TRUE, ("Test16 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }

    /* Test 17 */
    res = EMBX_ClosePort(remotePort);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test17 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }

    /* Test 18 */
    res = EMBX_CloseTransport(tp);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test18 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }
    
    /* Test 19 */
    res = EMBX_Deinit();
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test19 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }

    /* These test a different code path to the identical tests done before
     * EMBX_Init.
     */

    /* Test 20 - Depends on buffer2 not having been freed so we get through
     * to checking the state of the driver.
     */
    res = EMBX_SendMessage(remotePort, buffer2, 0);
    if(res != EMBX_INVALID_PORT)
    {
        EMBX_Info(EMBX_TRUE, ("Test20 failed, res = %s\n",error_strings[res]));
        bFailed = EMBX_TRUE;
    }

    /* Test 21 */
    res = EMBX_UnregisterTransport(factory);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test21 failed, res = %s\n",error_strings[res]));
        bFailed = EMBX_TRUE;
    }

    return bFailed?-1:0;

skip_remaining_tests:
    EMBX_Info(EMBX_TRUE, ("Skipping Remaining Tests\n"));
    return -1;
}
Esempio n. 7
0
int run_test(void)
{
EMBX_UINT    i;
EMBX_ERROR   res;
EMBX_TPINFO  tpinfo1;
EMBX_BOOL    bFailed;
EMBX_PORT    localPort,remotePort;
EMBX_VOID   *buffer1;
EMBX_FACTORY factory;

EMBX_RECEIVE_EVENT ev;

    bFailed = EMBX_FALSE;
    buffer1 = 0;

    /* Test 1 */
    res = EMBX_ReceiveBlock(EMBX_INVALID_HANDLE_VALUE, &ev);
    if(res != EMBX_INVALID_PORT)
    {
        EMBX_Info(EMBX_TRUE, ("Test1 failed, res = %s\n",error_strings[res]));
        bFailed = EMBX_TRUE;
    }

    res = EMBX_RegisterTransport(EMBXLB_loopback_factory, &loopback_config, sizeof(EMBXLB_Config_t), &factory);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Transport Registration failed, res = %s, exiting\n",error_strings[res]));
        goto skip_remaining_tests;
    }

    /* Test 2 */
    res = EMBX_Init();
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test2 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }

    /* Test 3 */
    res = EMBX_GetFirstTransport(&tpinfo1);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test3 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }


    /* Test 4 */
    res = EMBX_OpenTransport(tpinfo1.name, &tp);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test4 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }


    /* Test 5 */
    res = EMBX_CreatePort(tp, "testport", &localPort);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test5 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }

    
    /* Test 6 */
    res = EMBX_Connect(tp, "testport", &remotePort);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test6 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }

    /* Test 7 */
    res = EMBX_ReceiveBlock(tp, &ev);
    if(res != EMBX_INVALID_PORT)
    {
        EMBX_Info(EMBX_TRUE, ("Test7 failed, res = %s\n",error_strings[res]));
        bFailed = EMBX_TRUE;
    }
        
    /* Test 8 */
    res = EMBX_ReceiveBlock(remotePort, &ev);
    if(res != EMBX_INVALID_PORT)
    {
        EMBX_Info(EMBX_TRUE, ("Test8 failed, res = %s\n",error_strings[res]));
        bFailed = EMBX_TRUE;
    }

    /* Test 9 */
    res = EMBX_ReceiveBlock(localPort, 0);
    if(res != EMBX_INVALID_ARGUMENT)
    {
        EMBX_Info(EMBX_TRUE, ("Test9 failed, res = %s\n",error_strings[res]));
        bFailed = EMBX_TRUE;
    }


    /* Test 10 */
    res = EMBX_Alloc(tp, BUFFER_SIZE, &buffer1);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test10 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }

    for(i=0;i<BUFFER_SIZE;i++)
    {
        ((unsigned char *)buffer1)[i] = (unsigned char)i;
    }

    /* Test 11 */
    res = EMBX_SendMessage(remotePort, buffer1, BUFFER_SIZE);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test11 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }


    /* Test 12 */
    res = EMBX_ReceiveBlock(localPort, &ev);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test12 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }

    if(ev.handle != EMBX_INVALID_HANDLE_VALUE ||
       ev.offset != 0 ||
       ev.type   != EMBX_REC_MESSAGE ||
       ev.size   != BUFFER_SIZE)
    {
        EMBX_Info(EMBX_TRUE, ("Test13 failed, event structure incorrect\n"));
        goto skip_remaining_tests;
    }

    for(i=0;i<ev.size;i++)
    {
        if( ((unsigned char *)ev.data)[i] != (unsigned char)i )
        {
            EMBX_Info(EMBX_TRUE, ("Test13 failed, buffer contents incorrect\n"));
            bFailed = EMBX_TRUE;
            break;
        }
    }

    /* Test 13 */
    res = EMBX_Free(ev.data);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test13 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }

    if(!EMBX_OS_ThreadCreate(send_thread, (void *)remotePort, EMBX_DEFAULT_THREAD_PRIORITY, "send"))
    {
        EMBX_Info(EMBX_TRUE, ("Unable to create thread\n"));
        goto skip_remaining_tests;
    }

    /* Test 14 */
    res = EMBX_ReceiveBlock(localPort, &ev);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test14 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }

    if(ev.handle != EMBX_INVALID_HANDLE_VALUE ||
       ev.offset != 0 ||
       ev.type   != EMBX_REC_MESSAGE ||
       ev.size   != BUFFER_SIZE)
    {
        EMBX_Info(EMBX_TRUE, ("Test15 failed, event structure incorrect\n"));
        goto skip_remaining_tests;
    }

    /* Test 15 */
    res = EMBX_Free(ev.data);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test15 failed, res = %s\n",error_strings[res]));
        bFailed = EMBX_TRUE;
    }

    /* Test 16 */
    res = EMBX_ClosePort(remotePort);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test16 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }

    /* Test 17 */
    res = EMBX_ClosePort(localPort);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test17 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }

    /* Test 18 */
    res = EMBX_CloseTransport(tp);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test18 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }
    
    /* Test 19 */
    res = EMBX_Deinit();
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test19 failed, res = %s\n",error_strings[res]));
        goto skip_remaining_tests;
    }

    /* These test a different code path to the identical tests done before
     * EMBX_Init
     */

    /* Test 20 */
    res = EMBX_ReceiveBlock(localPort, &ev);
    if(res != EMBX_INVALID_PORT)
    {
        EMBX_Info(EMBX_TRUE, ("Test20 failed, res = %s\n",error_strings[res]));
        bFailed = EMBX_TRUE;
    }

    /* Test 21 */
    res = EMBX_UnregisterTransport(factory);
    if(res != EMBX_SUCCESS)
    {
        EMBX_Info(EMBX_TRUE, ("Test21 failed, res = %s\n",error_strings[res]));
        bFailed = EMBX_TRUE;
    }

    return bFailed?-1:0;

skip_remaining_tests:
    EMBX_Info(EMBX_TRUE, ("Skipping Remaining Tests\n"));
    return -1;
}
Esempio n. 8
0
MME_ERROR MME_AllocDataBuffer(MME_TransformerHandle_t handle, MME_UINT size,
			      MME_AllocationFlags_t flags, MME_DataBuffer_t ** dataBuffer_p) 
{
	static const MME_AllocationFlags_t illegalFlags = (MME_AllocationFlags_t)
		~(MME_ALLOCATION_PHYSICAL | MME_ALLOCATION_CACHED | MME_ALLOCATION_UNCACHED);

	Transformer_t *transformer;
	struct InternalDataBuffer *buf;
	unsigned localSize;

#ifndef MME_LEAN_AND_MEAN
        if (manager == NULL) {
 	        MME_Info( MME_INFO_MANAGER, (DEBUG_ERROR_STR "Driver not initialized\n"));
                return MME_DRIVER_NOT_INITIALIZED;      /* the manager must exist */
        }

	if (0 == size || NULL == dataBuffer_p || (flags & illegalFlags)) {
 	        MME_Info( MME_INFO_MANAGER, (DEBUG_ERROR_STR "size==0 ||  NULL == dataBuffer_p || (flags & illegalFlags)\n"));
		return MME_INVALID_ARGUMENT;
	}

	if (0 > (int) size) {
 	        MME_Info( MME_INFO_MANAGER, (DEBUG_ERROR_STR "size<0\n"));
		return MME_NOMEM;
	}
#endif

	/* lookup whether we should allocate using EMBX_OS_MemAlloc or EMBX_Alloc() */
	if (MME_SUCCESS != findTransformerInstance(handle, &transformer)) {
 	        MME_Info( MME_INFO_MANAGER, (DEBUG_ERROR_STR "invalid transformer handle\n"));
		return MME_INVALID_HANDLE;
	}
	if (0 == transformer->info) {
		/* this is a local transformers so we can't allocate memory using EMBX_Alloc */
		flags |= MME_ALLOCATION_CACHED;
	}

	/* Allocate the buffer structure */
	/* Cannot present a "negative" value to EMBX_OS_MemAlloc on SHLINUX KERNEL mode
         * as it "succeeds" and returns a non-NULL value
         */
        localSize = (int) (sizeof(*buf) + (flags & MME_ALLOCATION_CACHED ? size + MME_MAX_CACHE_LINE-1 : 0));
        if (0 > (int) localSize) {
 	        MME_Info( MME_INFO_MANAGER, (DEBUG_ERROR_STR "localSze <0\n"));
		return MME_NOMEM;
        }

	buf = EMBX_OS_MemAlloc(localSize);

	if (NULL == buf) {
 	        MME_Info( MME_INFO_MANAGER, (DEBUG_ERROR_STR "Cannot EMBX_OS_MemAlloc(%d)\n", 
                          sizeof(*buf) + (flags & MME_ALLOCATION_CACHED ? size : 0) ));
		return MME_NOMEM;
	}

	/* populate the buffer structure */
	memset(buf, 0, sizeof(*buf));
	buf->buffer.StructSize = sizeof(MME_DataBuffer_t);
	buf->buffer.NumberOfScatterPages = 1;
	buf->buffer.ScatterPages_p = buf->pages;
	buf->buffer.TotalSize = size;
	buf->flags = flags;
	buf->pages[0].Size = size;

	if (flags & MME_ALLOCATION_CACHED) {
		/* We MUST align the data buffer to a cacheline boundary to keep this safe */
		buf->pages[0].Page_p = (void *) MME_CACHE_LINE_ALIGN((buf + 1));
	} else {
		/* if transportHandle is 0 this will fail so we have no specific path to
		 * prevent uncached allocations for local transformers.
		 */
		EMBX_ERROR err = EMBX_Alloc(transformer->info->handle, size, 
					    &buf->pages[0].Page_p);

		if (EMBX_SUCCESS != err) {
     	                MME_Info( MME_INFO_MANAGER, (DEBUG_ERROR_STR "Cannot EMBX_Alloc(0x%08x, %d, 0x%08x)\n",
                                                     transformer->info->handle, size, (unsigned) &buf->pages[0].Page_p));
			EMBX_OS_MemFree(buf);
			return MME_NOMEM;
		}
	}

	*dataBuffer_p = &(buf->buffer);
	return MME_SUCCESS;
}