Raw-os Source code Analysis of the message system-queue_size

Source: Internet
Author: User
Tags message queue

The kernel version number of the analysis is as of 2014-04-15. Based on the 1.05 official version. Blogs will be in time to follow up the latest version of the kernel development progress, if the source code staring "??? "The words are not in the understanding of the part."

Raw-os Official site:http://www.raw-os.org/

Raw-os Escrow Address:https://github.com/jorya/raw-os/

With the foundation of the previous talk queue, this time say queue_size This module, the previous talk of queue communication, knowing that the queue is in communication, in order to speed up the transfer of data. is not to send the details of the data directly. Instead, a pointer to the user's data is sent. And this pointer is a void pointer. When you remove data from a queue, cast the pointer type of the void pointer to the original data content being sent. The raw data can be obtained accurately.

So queue_size, this is the pointer to the raw data, and the variable that represents the original data size, and then package it into a new MSG. This msg is called the msg of queue_size.

watermark/2/text/ahr0cdovl2jsb2cuy3nkbi5uzxqvdg9ydg9pc2vjagfu/font/5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/ Dissolve/70/gravity/southeast ">

This packaged msg is a basic unit for queue_size storage. Each unit is a queue_size msg. This msg includes a pointer to the user sending data segment void *msg_ptr. And the size of the user data segment msg_size.

also noted. Another *next pointer exists, and this *next pointer is a single linked list of these msg exist, learning the data structure of children's shoes know ~

Now, combine the queue and queue_size to summarize and then look at the different ways Queue_size and queue are represented in the kernel

1. In a queue, a message is a void pointer that can point to whatever data type

2. In queue_size, the message is a void pointer that can point to whatever data type and a characterization data size msg_size variable wrapper

In a queue, a queue message is implemented by an array of pointers ~

watermark/2/text/ahr0cdovl2jsb2cuy3nkbi5uzxqvdg9ydg9pc2vjagfu/font/5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/ Dissolve/70/gravity/southeast ">

Then you'll be able to tell you in a very responsible way, queue_size. Storing queue_size messages is achieved through a one-way linked list ~

In fact, the individual believes that the implementation of Queue_size message storage, the same can be used in the structure of the pointer array to implement, but so that users need to customize the MSG structure, always feel weird, assuming the kernel encapsulated queue_size MSG. The user simply passes in a void pointer that receives data, and a variable that receives the data size can ~

It feels like the API's a ghost.

Good ~ now know what is queue_size msg. and Queue_size msg in the kernel storage form. So the point to tell you is. Raw-os also queue_size the difference between the empty message and the detailed message, which means that the msg that holds the queue_size is divided into two linked lists, one that I call a message list. A list of messages called spare, what is this???

watermark/2/text/ahr0cdovl2jsb2cuy3nkbi5uzxqvdg9ydg9pc2vjagfu/font/5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/ Dissolve/70/gravity/southeast ">

In fact also very easy,queue_size initialization, the memory space Queue_size used to store queue_size msg is initialized into a spare message list, and then when the Queue_size msg is sent to the destination, A message is drawn from the spare message list. Then the queue_size linked list that holds the message is the message chain list ~

After you clear these points, you can see how the code for Raw-os is implemented.

Here are some of the main functions of queue_size with gaze, which are actually created. Send, receive the only ~

Creation of 1.queue_size

Raw_u16 raw_queue_size_create (raw_queue_size *p_q, Raw_u8 *p_name, raw_msg_size *msg_start, MSG_SIZE_TYPE number) {RAW_    Msg_size *P_MSG1;    Raw_msg_size *P_MSG2; /* Check Create Message Queue boundary conditions */#if (Raw_queue_size_function_check > 0) if (p_q = = 0) {return raw_null_object;} /* * The starting address of the incoming message block. Here is a level two pointer, usually passing in the first address of the array pointer * For example in the application layer definition, void* msg[size]. Then Msg[size] is an array. Msg=msg[0] is the first address of the array. &msg is the value of incoming &msg when the first address of the array pointer is passed in. This value is generally forced into the form (raw_void * *) &msg, insignificant, the array pointer is passed in the first address * * assumes undefined message array stored. Error returned */if (Msg_start = = 0) {return raw_null_pointer;} /* The size of the message array that stores the message needs to be specified when the queue is created, such as void* msg[10]. So here is 10, 0 error return */if (number = = 0) {return raw_zero_number;} #endif/* Initialize the blocked list for queue */list_init (&p_q->common_block_obj.block_list);/* Queue name */p_q->common_block_ Obj.name = p_name;/* Queue blocking mode */p_q->common_block_obj.block_way = raw_blocked_way_prio;/* Current_ Numbers represents the current number of messages in the message array */p_q->queue_current_msg = 0;/* Queue History Maximum number of messages */p_q->peak_numbers = 0;/* the size of the message array that stores messages */p_ Q->queue_msg_size = message start address in number;/* queue, different from normal queue, where Msg_start points to queue_size remaining spare element list */p_q->free_msg = msg_start;/* * Spare message list Initialization * * In Queue_size, the message array is no longer a void pointer, but an element of type Raw_msg_size * When queue_size organization raw_msg_size type message. Divided into two lists, the first is the message list, the second is the spare message list * Here is the spare message list */P_MSG1 = MSG_START;P_MSG2 = Msg_start;p_msg2++;while (--number) {p_msg1- >next = P_msg2;p_msg1->msg_ptr = 0;p_msg1->msg_size = 0;p_msg1++;p _msg2++;} /* The last element of the spare message list. That is, the tail of the list, pointing to whatever element, that is, the message chain list and the spare message list are unidirectional linked lists */p_msg1->next = 0;p_msg1->msg_ptr = 0;p_msg1->msg_size = 0;/* The initial queue control block object is Raw-os Message Queuing object Type */p_q->common_block_obj.object_type = Raw_queue_size_obj_type; Trace_queue_size_create (raw_task_active, p_q); return raw_success;}

2. Sending queue_size messages

For queue_size still have the end of the sent Queue_size or send to the front end of the Queue_size send selection, depending on the urgency of the user decision message

Raw_u16 raw_queue_size_create (raw_queue_size *p_q, Raw_u8 *p_name, raw_msg_size *msg_start, MSG_SIZE_TYPE number) {RAW_    Msg_size *P_MSG1;    Raw_msg_size *P_MSG2; /* Check Create Message Queue boundary conditions */#if (Raw_queue_size_function_check > 0) if (p_q = = 0) {return raw_null_object;} /* * The starting address of the incoming message block, here is a level two pointer, usually passing in the first address of the array pointer * such as in the application layer definition, void* msg[size], then msg[size] is an array, msg=msg[0] is the first address of the array. &msg is the first address of the array pointer * is passed in the value of &msg, generally will be forced to the value of (raw_void * *) &msg in the form of incoming, insignificant, the array pointer is passed in the first address * * assumes undefined message array stored. Error returned */if (Msg_start = = 0) {return raw_null_pointer;} /* The size of the message array to store the message, which needs to be specified when creating the queue, for example, void* msg[10], then 10 is passed in, 0 error returned */if (number = = 0) {return raw_zero_number;} #endif/* Initialize the blocked list for queue */list_init (&p_q->common_block_obj.block_list);/* Queue name */p_q->common_block_ Obj.name = p_name;/* Queue blocking mode */p_q->common_block_obj.block_way = raw_blocked_way_prio;/* Current_ Numbers represents the current number of messages in the message array */p_q->queue_current_msg = 0;/* Queue History Maximum number of messages */p_q->peak_numbers = 0;/* the size of the message array that stores messages */p_ Q->queue_msg_size = message start address in number;/* queue, different from normal queue, where Msg_start points to queue_size remaining spare element list */p_q->free_msg = msg_start;/* * Spare message list Initialization * * in Queue_size. The message array is no longer a void pointer, but an element of type Raw_msg_size * in queue_size organization raw_msg_size type message, divided into two lists, the first is the message chain list, the second is the spare message chain list * Here is the spare message chain list * * P_MSG1 = MSG_START;P_MSG2 = Msg_start;p_msg2++;while (--number) {p_msg1->next = P_msg2;p_msg1->msg_ptr = 0;p_msg1- >msg_size = 0;p_msg1++;p _msg2++;} /* The last element of the spare message list. That is, the tail of the list, pointing to whatever element, that is, the message chain list and the spare message list are unidirectional linked lists */p_msg1->next = 0;p_msg1->msg_ptr = 0;p_msg1->msg_size = 0;/* The initial queue control block object is Raw-os Message Queuing object Type */p_q->common_block_obj.object_type = Raw_queue_size_obj_type; Trace_queue_size_create (raw_task_active, p_q); return raw_success;}

3. Receive queue_size messages

Raw_u16 raw_queue_size_receive (raw_queue_size *p_q, Raw_tick_type wait_option, raw_void **msg_ptr, MSG_SIZE_TYPE * receive_size) {raw_u16 result; Raw_msg_size *msg_tmp; Raw_sr_alloc ();/* Check for interrupt nesting, and user-set receive blocking flag, only if user settings do not receive messages when blocking ability to receive messages in interrupts */#if (Raw_queue_size_function_check > 0) if ( Raw_int_nesting && (wait_option! = raw_no_wait)) {return RAW_NOT_CALLED_BY_ISR;} /* Check the address of the incoming Message Queuing control block. is empty. Description no entity, Error returned */if (p_q = = 0) {return raw_null_object;} /* Here is the variable that is used to store the data after receiving the data. A level two pointer */if (msg_ptr = = 0) {return raw_null_pointer;} /* Here is a variable to hold the message size after receiving the data. An int or uint can be */if (receive_size = = 0) {return raw_null_pointer;} #endif/* When task 0 is turned on, the message is forwarded by task 0??? */#if (Config_raw_zero_interrupt > 0) if (raw_int_nesting) {return RAW_NOT_CALLED_BY_ISR;} #endifRAW_CRITICAL_ENTER ();/* Assume that the type object of the incoming queue control is not a Raw-os queue object. Error returned */if (p_q->common_block_obj.object_type! = Raw_queue_size_obj_type) {raw_critical_exit (); return RAW_ERROR_ object_type;} /* * Get the implementation of messages in Queue_size * * Infer if queue_size has a message, assuming not. Want to get Queue_sizeThe task is blocked * when there is a message: * 1. Temporary message msg_tmp points to the read pointer.      Since the read pointer points to the first message in the message chain, Msg_tmp points to the first message * 2. The incoming content pointer that holds the QUEUE_SIZE message points to the content pointer in the first message * 3. The size variable of the incoming storage queue_size message becomes the size of the first message * 4. The read pointer of the message list moves back to the next message * 5. Reclaims messages that are read by the message list. Empty and return to spare message chain list * */IF (P_Q->QUEUE_CURRENT_MSG) {/* point to read pointer */msg_tmp = p_q->read;/* Read Queue_size message content */*msg_ptr = m sg_tmp->msg_ptr;/* read Queue_size message size */*receive_size = msg_tmp->msg_size;/* Read pointer back */p_q->read = Msg_tmp-&gt    ; next; /* The message list is not empty (the last message in the message chain list is the next message link is 0).    The number of messages that exist in the message list--*/if (p_q->read) {p_q->queue_current_msg--; }/* When the message list is empty, the write pointer is 0.    Number of messages clear 0 */else {p_q->write = 0;p_q->queue_current_msg = 0; }/* Recycles the message list to read the message memory space, adding to the spatial message list */msg_tmp->next = P_q->free_msg;p_q->free_msg = msg_tmp; Raw_critical_exit (); Trace_queue_size_get_msg (raw_task_active, P_q, wait_option, *msg_ptr, *receive_size); return raw_success;} /* When the user sets no clogging flag, returns a null pointer queue_size message with a size of 0 */if (wait_option = = raw_no_wait) {*msg_ptr = 0;*receive_size   = 0; Raw_critical_exit (); return raw_no_pend_wait;} System_lock_process_queue_size ();/* When queue_size has no message. Plug in the message to get queue_size. Blockage to the queue_size clogging of the list */raw_pend_object ((Raw_common_block_object *) p_q, raw_task_active, wait_option); Raw_critical_exit (); Trace_queue_size_get_block (raw_task_active, P_q, wait_option);/* System Task scheduling */raw_sched ();/* Get blocked when the task is scheduled to return status */result = Block_state_post_process (raw_task_active, 0);/* Assuming that the blocking task is queue_size the presence of messages dispatched, not because of congestion timeouts, and so on, the queue_size message is obtained */if ( result = = raw_success) {/* Before the post msg has been parsed. The message is sent directly to the task control block, and when the blocking task is dispatched, the message is taken from the task control block to MSG, returning to the scheduled blockage state */*receive_size = Raw_task_active->msg_size;*msg_ptr = Raw_ Task_active->msg;} else {*msg_ptr = 0;*receive_size = 0;} return result;}


Raw-os Source code Analysis of the message system-queue_size

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.