From: <nmd...@us...> - 2009-03-12 18:26:31
|
Revision: 355 http://aceos.svn.sourceforge.net/aceos/?rev=355&view=rev Author: nmdilipsimha Date: 2009-03-12 18:25:55 +0000 (Thu, 12 Mar 2009) Log Message: ----------- Modifed wait events to handle various options. Modified Paths: -------------- src/include/kernel/ipc.h src/include/kernel/pm/task.h src/include/kernel/wait_event.h src/kernel/ipc/message_queue.c src/kernel/parameter.c Modified: src/include/kernel/ipc.h =================================================================== --- src/include/kernel/ipc.h 2009-03-12 09:54:00 UTC (rev 354) +++ src/include/kernel/ipc.h 2009-03-12 18:25:55 UTC (rev 355) @@ -6,37 +6,56 @@ #ifndef IPC_H #define IPC_H +typedef struct message_queue MESSAGE_QUEUE, *MESSAGE_QUEUE_PTR; + #include <ace.h> #include <ds/list.h> #include <sync/spinlock.h> #include <kernel/system_call_handler.h> +#include <kernel/wait_event.h> #define MESSAGE_QUEUE_NO_WAIT -1 #define MESSAGE_QUEUE_CAN_WAIT 0 extern UINT32 max_message_queue_length; /* System wide tunable to control the size of message queue in task structure */ -enum MESSAGE_BUFFER_TYPE +typedef enum message_type { - MESSAGE_BUFFER_TYPE_VALUE, - MESSAGE_BUFFER_TYPE_BUFFER -}; + MESSAGE_TYPE_VALUE, + MESSAGE_TYPE_REFERENCE, + MESSAGE_TYPE_SKIP +}MESSAGE_TYPE; +#define ARG_ADDRESS_INDEX 0 +#define ARG_LENGTH_INDEX 1 +#define ARG1_INDEX 2 +#define ARG2_INDEX 3 +#define TOTAL_ARG_COUNT 4 typedef struct message_buffer { - LIST message_buffer_queue; - enum MESSAGE_BUFFER_TYPE type; /* type=0 means In VALUE; type=1 means In BUFFER */ - UINT32 args[TOTAL_SYSTEM_CALL_ARGS]; - UINT32 from_pid; + LIST message_buffer_queue; + MESSAGE_TYPE type; + UINT32 args[TOTAL_ARG_COUNT]; }MESSAGE_BUFFER, *MESSAGE_BUFFER_PTR; +struct message_queue +{ + SPIN_LOCK lock; /*! Lock to guard the entire mesage queue */ + UINT32 buf_count; /*! Number of message buffers that are present in this queue */ + MESSAGE_BUFFER_PTR msg_queue; /*! Pointer to head of the message buffer queue */ + WAIT_EVENT_PTR wait_event_msg_queue; /*! Pointer to wait event queue for message_queue variable */ + SPIN_LOCK wait_event_msg_queue_lock; /*! lock for the wait event */ +}; +ERROR_CODE SendMessage(MESSAGE_TYPE type, register unsigned int arg1, register unsigned int arg2, register unsigned int arg3, register unsigned int arg4, UINT32 pid_target_task, UINT8 queue_no, UINT32 wait_time); +ERROR_CODE SendMessageCore(MESSAGE_TYPE type, register unsigned int arg1, register unsigned int arg2, register unsigned int arg3, register unsigned int arg4, MESSAGE_QUEUE_PTR message_queue, UINT32 wait_time); +ERROR_CODE ReceiveMessage(MESSAGE_TYPE type, unsigned int *arg1, unsigned int *arg2, unsigned int *arg3, unsigned int *arg4, UINT8 queue_no, UINT32 wait_time); +ERROR_CODE ReceiveMessageCore(MESSAGE_TYPE type, unsigned int *arg1, unsigned int *arg2, unsigned int *arg3, unsigned int *arg4, MESSAGE_QUEUE_PTR message_queue, UINT32 wait_time); +UINT32 GetTotalMessageCount(MESSAGE_QUEUE_PTR msg_queue); +void SkipMessage(MESSAGE_QUEUE_PTR msg_queue); +ERROR_CODE GetNextMessageInfo(UINT32 *type, UINT32 *length, MESSAGE_QUEUE_PTR msg_queue); -#include <kernel/pm/task.h> -ERROR_CODE SendMessage(MESSAGE_BUFFER_PTR mbuf, UINT32 pid_target_task, UINT8 queue_no, UINT32 wait_time); -ERROR_CODE ReceiveMessage(MESSAGE_BUFFER_PTR mbuf, UINT8 queue_no, UINT32 wait_time); - #endif Modified: src/include/kernel/pm/task.h =================================================================== --- src/include/kernel/pm/task.h 2009-03-12 09:54:00 UTC (rev 354) +++ src/include/kernel/pm/task.h 2009-03-12 18:25:55 UTC (rev 355) @@ -14,7 +14,6 @@ #include <kernel/pm/thread.h> #include <kernel/pm/pid.h> #include <kernel/ipc.h> -#include <kernel/wait_event.h> /*\todo remove these macros and put it as tunable*/ #define TASK_CACHE_FREE_SLABS_THRESHOLD 100 @@ -36,11 +35,7 @@ THREAD_PTR thread_head; /*! threads in the same task */ - SPIN_LOCK message_queue_lock[MESSAGE_QUEUES_PER_TASK]; - MESSAGE_BUFFER_PTR message_queue[MESSAGE_QUEUES_PER_TASK]; /*! Pointer to head of the message buffer queue */ - WAIT_EVENT_PTR wait_event_message_queue[MESSAGE_QUEUES_PER_TASK]; /*! Pointer to wait event queue for message queue variable */ - SPIN_LOCK wait_event_lock[MESSAGE_QUEUES_PER_TASK]; - UINT32 message_queue_length; /*! Number of message buffers that can be present in the queue */ + MESSAGE_QUEUE message_queue[MESSAGE_QUEUES_PER_TASK]; /*! Pointer to message queue containing IPC messages */ }; extern CACHE task_cache; Modified: src/include/kernel/wait_event.h =================================================================== --- src/include/kernel/wait_event.h 2009-03-12 09:54:00 UTC (rev 354) +++ src/include/kernel/wait_event.h 2009-03-12 18:25:55 UTC (rev 355) @@ -10,7 +10,8 @@ #include <ace.h> #include <ds/list.h> -#include <kernel/pm/task.h> +//#include <kernel/pm/task.h> +/* This is to avoid circular dependency in header files. Just don't use THREAD_PTR in this file, but use struct thread* instead. */ #define WAIT_EVENT_WAKE_UP_ALL 1 @@ -19,7 +20,7 @@ struct wait_event { - THREAD_PTR thread; /*Pointer to thread which is waiting on this event */ + struct thread *thread; /*Pointer to thread which is waiting on this event */ BYTE fired; /* Indicates if this event got fired(1) or just got removedi(0) because soe other related event fired */ LIST in_queue; /*List of events in this queue bucket. Each of these events will point to different threads. */ LIST thread_events; /* List of events which belong to same thread */ Modified: src/kernel/ipc/message_queue.c =================================================================== --- src/kernel/ipc/message_queue.c 2009-03-12 09:54:00 UTC (rev 354) +++ src/kernel/ipc/message_queue.c 2009-03-12 18:25:55 UTC (rev 355) @@ -9,21 +9,20 @@ #include <string.h> #include <kernel/debug.h> -UINT32 max_message_queue_length; /* System wide tunable to control the size of message queue in task structure */ +UINT32 max_message_queue_length; /* System wide tunable to control the size of message queue in message_queue structure */ -/*! \brief Sends a message from current task to the task specified. Holds target task's message queue lock accross the life time of function. - * If flag contains NO_WAIT, then this will return with error if queue is full. By default it will wait indefinitely until it places the message on the queue. - * \param mbuf Contains Message buffer. - * \param pid_target_task_task Pid of target task to which the message has to be posted. - * \param queue_no Offset to task->message_queue array. - * \param wait_time Indicates how much time the sender can wait till the message is sent. +/*! \brief Wrapper to SendMessageCore. + * \param type Indicates message type as ByValue or ByReference + * \param arg1 Pointer to data buffer in user space of size atleast *arg2 or arg1(ByValue). + * \param arg2 Length of message that needs to be copied or arg2(ByValue). + * \param arg3 Store to hold optional arg1 or arg3(ByValue) + * \param arg4 Store to hold optional arg2 or arg4(ByValue) + * \param pid_target_task Pid of target task to which the message has to be posted. + * \param queue_no Offset to task->message_queue array. + * \param wait_time Indicates how much time the sender can wait till the message is sent. */ -ERROR_CODE SendMessage(MESSAGE_BUFFER_PTR mbuf, UINT32 pid_target_task, UINT8 queue_no, UINT32 wait_time) +ERROR_CODE SendMessage(MESSAGE_TYPE type, register unsigned int arg1, register unsigned int arg2, register unsigned int arg3, register unsigned int arg4, UINT32 pid_target_task, UINT8 queue_no, UINT32 wait_time) { - MESSAGE_BUFFER_PTR kern_msg_buf; - ERROR_CODE error_ret = ERROR_SUCCESS;; - WAIT_EVENT_PTR my_wait_event; - int loop; TASK_PTR to_task; assert(queue_no < MESSAGE_QUEUES_PER_TASK); @@ -31,136 +30,269 @@ to_task = PidToTask(pid_target_task); if(to_task == NULL) return ERROR_INVALID_PARAMETER; - SpinLock( &(to_task->message_queue_lock[queue_no]) ); + return SendMessageCore(type, arg1, arg2, arg3, arg4, &(to_task->message_queue[queue_no]), wait_time); +} - if( (wait_time == MESSAGE_QUEUE_NO_WAIT) && (to_task->message_queue_length >= max_message_queue_length) ) +/*! \brief Sends a message from current task to the message queue specified. Holds target message queue's lock accross the life time of function. + * If wait_time contains NO_WAIT, then this will return with error if queue is full. By default it will wait indefinitely until it places the message on the queue. + * \param type Indicates message type as ByValue or ByReference + * \param arg1 Pointer to data buffer in user space of size atleast *arg2. + * \param arg2 Length of message that needs to be copied. + * \param arg3 Store to hold optional argument1 + * \param arg4 Store to hold optional argument2 + + * \param message_queue Pointer to target message queue, where the message has to be delivered. + * \param wait_time Indicates how much time the sender can wait till the message is sent. + */ +ERROR_CODE SendMessageCore(MESSAGE_TYPE type, register unsigned int arg1, register unsigned int arg2, register unsigned int arg3, register unsigned int arg4, MESSAGE_QUEUE_PTR message_queue, UINT32 wait_time) +{ + MESSAGE_BUFFER_PTR kern_msg_buf; + ERROR_CODE error_ret = ERROR_SUCCESS;; + WAIT_EVENT_PTR my_wait_event; + UINT32 ret_time; + WAIT_EVENT_PTR wait_queue; + SPIN_LOCK_PTR wait_lock; + + if(message_queue == NULL) + return ERROR_INVALID_PARAMETER; + + SpinLock( &(message_queue->lock) ); + + /*Sending this message depends on queue length and wait time */ + if(message_queue->buf_count >= max_message_queue_length) { - SpinUnlock( &(to_task->lock) ); - return ERROR_NOT_ENOUGH_MEMORY; - } - else if( (wait_time == MESSAGE_QUEUE_CAN_WAIT) && (to_task->message_queue_length >= max_message_queue_length) ) - { - /* Wait for this message queue to become thin */ - my_wait_event = AddToEventQueue( &(to_task->wait_event_message_queue[queue_no]) ); - SpinUnlock( &(to_task->message_queue_lock[queue_no]) ); /* We need to unlock because we block in WaitForEvent */ - WaitForEvent(my_wait_event, wait_time); - SpinLock( &(to_task->message_queue_lock[queue_no]) ); /* take the lock again because we have returned from blocked state */ - assert(my_wait_event->fired == 1); - kfree(my_wait_event); - } + if( wait_time == MESSAGE_QUEUE_NO_WAIT ) + { + SpinUnlock( &(message_queue->lock) ); + return ERROR_NOT_ENOUGH_MEMORY; + } + else if( wait_time != MESSAGE_QUEUE_NO_WAIT ) + { + wait_queue = message_queue->wait_event_msg_queue; + wait_lock = &(message_queue->wait_event_msg_queue_lock); + /* Wait for this message queue to become thin */ + SpinLock( wait_lock ); + my_wait_event = AddToEventQueue( &wait_queue ); + SpinUnlock( wait_lock ); + if(wait_time == MESSAGE_QUEUE_CAN_WAIT) + wait_time = 0; + + SpinUnlock( &(message_queue->lock) ); + ret_time = WaitForEvent(my_wait_event, wait_time); + SpinLock( &(message_queue->lock) ); /* take the lock again because we have returned from blocked state */ + + if(ret_time == 0) /* no event fired and we timeout out */ + { + SpinUnlock( &(message_queue->lock) ); + return ERROR_NOT_ENOUGH_MEMORY; + } + + assert(my_wait_event->fired == 1); + + SpinLock( wait_lock ); + RemoveEventFromQueue( my_wait_event, &wait_queue); + SpinUnlock( wait_lock ); + + kfree(my_wait_event); + } + } kern_msg_buf = (MESSAGE_BUFFER_PTR)kmalloc(sizeof(MESSAGE_BUFFER), KMEM_NO_FAIL); - kern_msg_buf->from_pid = GET_CURRENT_PID(); InitList( &(kern_msg_buf->message_buffer_queue) ); + kern_msg_buf->type = type; - switch( mbuf->type) + switch(type) { - case MESSAGE_BUFFER_TYPE_VALUE: /* In value */ - for(loop=0 ; loop < TOTAL_SYSTEM_CALL_ARGS ; loop++) - kern_msg_buf->args[loop] = mbuf->args[loop]; + case MESSAGE_TYPE_VALUE: /* In value */ + kern_msg_buf->args[0] = arg1; + kern_msg_buf->args[1] = arg2; + kern_msg_buf->args[2] = arg3; + kern_msg_buf->args[3] = arg4; break; - case MESSAGE_BUFFER_TYPE_BUFFER: /* In buffers. Copy the message inside buffer from this user space to target user space */ - /* args[0] will contain start address and args[1] will contain length of the buffer. */ - if(mbuf->args[0] == NULL || mbuf->args[1] < 0 || mbuf->args[1] > PAGE_SIZE) + case MESSAGE_TYPE_REFERENCE: /* In buffers. Copy the message inside buffer from this user space to target user space */ + /* args[0] will contain start address and args[1] will contain length of the buffer. args[2] and args[3] contain optional storage for values */ + if(arg1 == NULL || arg2 < 0 || arg2 > PAGE_SIZE) return ERROR_INVALID_PARAMETER; - kern_msg_buf->args[0] = (UINT32)kmalloc(mbuf->args[1], KMEM_NO_FAIL); - (void)memcpy((void*)kern_msg_buf->args[0], (const void*)(mbuf->args[0]), mbuf->args[1]); + + kern_msg_buf->args[ARG_ADDRESS_INDEX] = (UINT32)kmalloc(arg2, KMEM_NO_FAIL); + (void)memcpy((void*)kern_msg_buf->args[ARG_ADDRESS_INDEX], (const void*)(arg1), arg2); + kern_msg_buf->args[ARG_LENGTH_INDEX] = arg2; + + /* Copy optional values in last 2 arguments */ + kern_msg_buf->args[ARG1_INDEX] = arg3; + kern_msg_buf->args[ARG2_INDEX] = arg4; break; default: return ERROR_INVALID_PARAMETER; } - AddToListTail( &(to_task->message_queue[queue_no]->message_buffer_queue), &(kern_msg_buf->message_buffer_queue) ); - SpinUnlock( &(to_task->lock) ); + if(message_queue->msg_queue == NULL) + message_queue->msg_queue = kern_msg_buf; + else + AddToListTail( &(message_queue->msg_queue->message_buffer_queue), &(kern_msg_buf->message_buffer_queue) ); + + message_queue->buf_count++; + SpinUnlock( &(message_queue->lock) ); return error_ret; } /*! \brief Receives a message present in the tasks's message queue. * Holds task lock accross the life time of function. - * \param mbuf Pointer to an empty message buffer allocated(malloced) by user. This will be loaded with the required message. mbuf->type will be specified from user. depending on this mbuf->args[0] and mbuf->args[1] will also be filled by user. + * \param type Indicates message type as ByValue or ByReference + * \param arg1 Pointer to data buffer in user space of size atleast *arg2. + * \param arg2 Length of message that needs to be copied. + * \param arg3 Store to hold optional argument1 + * \param arg4 Store to hold optional argument2 + * \param queue_no This is the index into message_queue array in task structure. * \param wait_time Time in seconds that the user wants to wait for the message. If 0, then it's non blocking, if -1, it's blocking forever. */ -ERROR_CODE ReceiveMessage(MESSAGE_BUFFER_PTR mbuf, UINT8 queue_no, UINT32 wait_time) +ERROR_CODE ReceiveMessage(MESSAGE_TYPE type, unsigned int *arg1, unsigned int *arg2, unsigned int *arg3, unsigned int *arg4, UINT8 queue_no, UINT32 wait_time) { - MESSAGE_BUFFER_PTR message_queue_ptr; - ERROR_CODE error_ret = ERROR_SUCCESS;; TASK_PTR my_task; - WAIT_EVENT_PTR my_wait_event; - UINT32 ret_timeout, loop; if(queue_no > MESSAGE_QUEUES_PER_TASK) return ERROR_INVALID_PARAMETER; my_task = GetCurrentThread()->task; - SpinLock( &(my_task->message_queue_lock[queue_no]) ); + return ReceiveMessageCore(type, arg1, arg2, arg3, arg4, &(my_task->message_queue[queue_no]), wait_time); +} - message_queue_ptr = my_task->message_queue[queue_no]; - if(wait_time==MESSAGE_QUEUE_CAN_WAIT) /* Wait till the desired message arrives */ +/*! \brief Receives a message present in the tasks's message queue. + * Holds task lock accross the life time of function. + * \param type Indicates message type as ByValue or ByReference + * \param arg1 Pointer to data buffer in user space of size atleast *arg2. + * \param arg2 Length of message that needs to be copied. + * \param arg3 Store to hold optional argument1 + * \param arg4 Store to hold optional argument2 + * \param message_queue Pointer to message queue from where message has to be fetched + * \param wait_time Time in seconds that the user wants to wait for the message. If 0, then it's non blocking, if -1, it's blocking forever. + */ +ERROR_CODE ReceiveMessageCore(MESSAGE_TYPE type, unsigned int *arg1, unsigned int *arg2, unsigned int *arg3, unsigned int *arg4, MESSAGE_QUEUE_PTR message_queue, UINT32 wait_time) +{ + WAIT_EVENT_PTR my_wait_event, wait_queue; + UINT32 ret_time; + MESSAGE_BUFFER_PTR rem_buf; + SPIN_LOCK_PTR wait_lock; + + if(message_queue == NULL) + return ERROR_INVALID_PARAMETER; + + SpinLock( &(message_queue->lock) ); + + if(message_queue->buf_count == 0) { - if(message_queue_ptr == NULL) + if(wait_time == MESSAGE_QUEUE_NO_WAIT) + return ERROR_NOT_FOUND; + else /* Wait till the desired message arrives for time specified in wait_time */ { - SpinUnlock( &(my_task->message_queue_lock[queue_no]) ); - my_wait_event = AddToEventQueue( &(my_task->wait_event_message_queue[queue_no]) ); - WaitForEvent(my_wait_event, 0); /* block forever until some message arrives */ - SpinLock( &(my_task->message_queue_lock[queue_no]) ); /* take the lock after returning from blocked state */ + wait_queue = message_queue->wait_event_msg_queue; + wait_lock = &(message_queue->wait_event_msg_queue_lock); + + SpinLock( wait_lock ); + my_wait_event = AddToEventQueue( &wait_queue ); + SpinUnlock( wait_lock ); + + if(wait_time == MESSAGE_QUEUE_CAN_WAIT) + wait_time = 0; + + SpinUnlock( &(message_queue->lock) ); + ret_time = WaitForEvent(my_wait_event, wait_time); /* Block till wait_time expires or until timer expires */ + SpinLock( &(message_queue->lock) ); + + if(ret_time == 0) /* timeout happened and our event didn't get fired */ + { + SpinUnlock( &(message_queue->lock) ); + return ERROR_NOT_FOUND; + } + + assert(my_wait_event->fired == 1 && message_queue->buf_count > 0); + + SpinLock( wait_lock); + RemoveEventFromQueue(my_wait_event, &wait_queue); + SpinUnlock( wait_lock); + /* we have got the message, so can continue fetching it */ } } - else if(wait_time==MESSAGE_QUEUE_NO_WAIT) - { - if(message_queue_ptr == NULL) - { - SpinUnlock( &(my_task->message_queue_lock[queue_no]) ); - return ERROR_NOT_FOUND; - } - } - else /* wait_time > 0 */ - { - search_queue: - if(message_queue_ptr == NULL) - { - if(wait_time < 0) - { - SpinUnlock( &(my_task->message_queue_lock[queue_no]) ); - return ERROR_NOT_FOUND; /* In case of missed wakeup's from WaitForEvent, wait time will be in -ve */ - } - my_wait_event = AddToEventQueue( &(my_task->wait_event_message_queue[queue_no]) ); - SpinUnlock( &(my_task->message_queue_lock[queue_no]) ); - ret_timeout = WaitForEvent(my_wait_event, wait_time); /* Block till wait_time expires or until any message arrives */ - if(ret_timeout == 0 || my_task->wait_event_message_queue[queue_no] == NULL) /* timeout happened and our event didn't get fired */ - return ERROR_NOT_FOUND; - else if(wait_time-ret_timeout > 0) /* ret_timeout is > 0 and < wait_time and indicates time left in sleep */ - { - assert(my_wait_event->fired == 1); - /* we got here because an even got fired before the timeout happened */ - SpinLock( &(my_task->message_queue_lock[queue_no]) ); - message_queue_ptr = my_task->message_queue[queue_no]; - wait_time -= ret_timeout; - goto search_queue; - } - /* we have got the message, so can continue fetching it */ - SpinLock( &(my_task->message_queue_lock[queue_no]) ); /* take the lock after returning from blocked state */ - } - } + rem_buf = message_queue->msg_queue; + message_queue->buf_count--; + + if(message_queue->buf_count == 0) + message_queue->msg_queue = NULL; + else + message_queue->msg_queue = STRUCT_ADDRESS_FROM_MEMBER((rem_buf->message_buffer_queue).next, MESSAGE_BUFFER, message_buffer_queue); - RemoveFromList( &(message_queue_ptr->message_buffer_queue) ); + RemoveFromList( &(rem_buf->message_buffer_queue) ); - switch(mbuf->type) + switch(type) { - case MESSAGE_BUFFER_TYPE_VALUE: /* In value */ - for(loop=0 ; loop < TOTAL_SYSTEM_CALL_ARGS ; loop++) - mbuf->args[loop] = message_queue_ptr->args[loop]; + case MESSAGE_TYPE_SKIP: + break; + case MESSAGE_TYPE_VALUE: /* In value */ + if(arg1 == NULL || arg2 == NULL || arg3 == NULL || arg4 == NULL) + return ERROR_INVALID_PARAMETER; + + *arg1 = rem_buf->args[0]; + *arg2 = rem_buf->args[1]; + *arg3 = rem_buf->args[2]; + *arg4 = rem_buf->args[3]; break; - case MESSAGE_BUFFER_TYPE_BUFFER: /* In buffers. Copy the message inside buffer from this user space to target user space */ - (void)memcpy((void*)(mbuf->args[0]), (const void*)message_queue_ptr->args[0], mbuf->args[1]); + case MESSAGE_TYPE_REFERENCE: /* In buffers. Copy the message inside buffer from this user space to target user space */ + if(arg1 == NULL || arg2 == NULL || arg3 == NULL || arg4 == NULL || (arg2!=NULL && *arg2 < 0) ) + return ERROR_INVALID_PARAMETER; + + (void)memcpy((void*)(*arg1), (const void*)rem_buf->args[ARG_ADDRESS_INDEX], *arg2); + /* Copy values in last 2 arguments */ + *arg3 = rem_buf->args[ARG1_INDEX]; + *arg4 = rem_buf->args[ARG2_INDEX]; break; } - SpinUnlock( &(my_task->message_queue_lock[queue_no]) ); - return error_ret; + kfree(rem_buf); + SpinUnlock( &(message_queue->lock) ); + return ERROR_SUCCESS; } + +UINT32 GetTotalMessageCount(MESSAGE_QUEUE_PTR msg_queue) +{ + return msg_queue->buf_count; +} + +void SkipMessage(MESSAGE_QUEUE_PTR msg_queue) +{ + ReceiveMessageCore(MESSAGE_TYPE_SKIP, NULL, NULL, NULL, NULL, msg_queue, MESSAGE_QUEUE_NO_WAIT); +} + + +ERROR_CODE GetNextMessageInfo(UINT32 *type, UINT32 *length, MESSAGE_QUEUE_PTR msg_queue) +{ + MESSAGE_BUFFER_PTR my_buf; + + if(msg_queue == NULL) + return ERROR_INVALID_PARAMETER; + + SpinLock( &(msg_queue->lock) ); + + if(msg_queue->buf_count <= 1) + { + SpinUnlock( &(msg_queue->lock) ); + return ERROR_NOT_FOUND; + } + + my_buf = STRUCT_ADDRESS_FROM_MEMBER( (msg_queue->msg_queue->message_buffer_queue).next, MESSAGE_BUFFER, message_buffer_queue ); + if(my_buf == msg_queue->msg_queue) + { + kprintf("message_queue=%p buf_count=%d\n", msg_queue, msg_queue->buf_count); + SpinUnlock( &(msg_queue->lock) ); + panic("GetNextMessageInfo: message queue garbled\n"); + } + + *type = my_buf->type; + *length = my_buf->args[3]; + return ERROR_SUCCESS; +} Modified: src/kernel/parameter.c =================================================================== --- src/kernel/parameter.c 2009-03-12 09:54:00 UTC (rev 354) +++ src/kernel/parameter.c 2009-03-12 18:25:55 UTC (rev 355) @@ -18,11 +18,14 @@ static COMPARISION_RESULT compare_kernel_parameter(char * data1, char * data2); static KERNEL_PARAMETER_PTR FindKernelParameter(char * parameter_name); +extern UINT32 max_message_queue_length; + /*! global kernel parameters*/ static KERNEL_PARAMETER kernel_parameters[] = { {"gdb_port", &sys_gdb_port, UINT32Validator, {0, 0xFFFF, 0}, UINT32Assignor, NULL}, {"kmem_reserved_mem_size", &kmem_reserved_mem_size, UINT32Validator, {0, 1024*1024*1024, 0}, UINT32Assignor, NULL}, - {"limit_pmem", &limit_physical_memory, UINT32Validator, {8, (UINT32)4*1024*1024, 0}, UINT32Assignor, NULL} + {"limit_pmem", &limit_physical_memory, UINT32Validator, {8, (UINT32)4*1024*1024, 0}, UINT32Assignor, NULL}, + {"max_message_queue_length", &max_message_queue_length, UINT32Validator, {0, 1024, 0}, UINT32Assignor, NULL} }; /*! Initializes the kernel parameter*/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |