Linux C Obstack and linuxobstack

Source: Internet
Author: User

Linux C Obstack and linuxobstack

 

Introduction to Obstack

Obstack Initialization

Object applied in Obstack

Release object

Apply for growing object

Get Obstack status

Data Alignment

The following is an introduction to obstack from wiki:

Obstack is the GNU extension (actually gnu c library) for memory management in the C standard library ). Obstack = Object stack. Yes, Obstack is a stack. The elements in the stack are object objects (not object-oriented objects. Here, objects refer to data elements ). The data is dynamic, that is, the dynamic memory is used. This memory management technology belongs to Region-based memory management.

So what is region-based memory management? Region refers to the location where the data objects we applied for are stored. In this memory management mode, we put all the applied data objects together (of course, the address is not necessarily continuous. Aggregation is a logical structure, such as an Obstack stack ). The advantage is that memory can be released at one time for centralized management. Now you have a general understanding of Obstack.

The following is the Obstack description of gnu c:

Obstack is a memory pool that contains data object stacks.

What is a memory pool? The memory pool is also called a fixed-size block memory application (fixed-size blocks allocation). It is also a memory management technology. This technology allows dynamic memory application. (Confused? The above is fixed, and now it is dynamic. In fact, it is fixed to the total size, and dynamic refers to the actual memory application. If you have used virtual box, yes, it is something that will be installed by the person who just played linux 60 percent. When a virtual disk is created, the dynamic allocation is described as follows: The Virtual Disk gradually occupies the physical disk space [until the allocated size is reached], however, the physical hard disk space will not be automatically reduced when the internal space is not used]) This method is a bit similar to the new operation of malloc or C ++. But the malloc and new operations will cause memory fragmentation issues (don't hit me, This is what wiki says, it's none of my business ). The more effective way is to use the same size memory pool. Pre-applied and centrally managed. Applications can play freely in the memory pool and never go ashore-_-|.

Go back and talk about Obstack. You can create any number of independent obstacks and apply for objects in these obstacks. These objects follow the logical structure of the stack: The last applied object must be released first. Data in different Obstack is independent of each other and has no relationship. In addition to the requirements for the memory release sequence, obstack is very common: An Obstack can contain any number of objects of any size.

The implementation of the memory application in the Obstack is generally macro, which is very efficient. If you don't want to use macros (the reason is: convenient debugging), you can take a look at my other article. This article describes how to avoid using predefined macros. The only memory space loss is that different objects may need to be filled with memory, so that each object starts with the appropriate boundary line, which is actually to exchange space for time.

The Obstack is a struct: struct obstack. This structure has a very small fixed size, which records the status of the obstack and how to find the objects in the Obstack. However, the obstack struct itself does not contain any objects. Do not want to directly explore the content of struct obstack. You must use the specified function.

You can create an obstack by declaring a struct obstack variable. Alternatively, you can dynamically apply for a struct obstack * obstack = (struct obstack *) malloc (sizeof (struct obstack). You can also use obstack in the obstack, as mentioned in the gnu c library Documentation)

All functions used by the Obstack must specify the obstack to be used. Objects in the Obstack will be packaged into a large memory block (called chunks ). The struct obstack structure Pointer Points to the currently used chunks.

A new chunk will be created whenever the requested object cannot be inserted into the previous chunk. In what form are these chunks connected together (linked list? Tree ?), We are not concerned about it. These are automatically managed by obstack. The chunk is automatically created by the obstack, But the creation method is determined by you. The malloc function is generally used directly or indirectly.

Lenovo memory pool we mentioned earlier: chunk is a fixed size pool. Obstack is just a kind of pool administrator: He told the person who came to take a bath to observe the rules, and finally he had to go first.

 

Obstack initialization:
#include<obstack.h>int obstack_init(struct obstack *obstack-ptr)

 

 

Obstack_init is actually a macro implementation. Obstack_init will automatically call the obstack_chunk_alloc function to apply for a chunk. Note that this is a macro and you need to specify the function to which the macro points. If the memory application fails, it will call the function pointed to by obstack_alloc_failed_handler. If yes, it is still a macro. If all objects in the chunk are released, the function pointed to by obstack_chunk_free is used to return the space occupied by the chunk. The current version of obstack_init always returns only 1 (the previous version will return 0 if it fails)

Instance:

# Include <obstack. h> # include <stdlib. h> # define optimize malloc # define obstack_chunk_free // apply for obstackstatic struct obstack myobstack; obstack_init (& myobstack); // apply for obstackstruct obstack * myobstack_ptr = (struct obstack *) malloc (sizeof (struct obstack) obstack_init (myobstack_ptr)

The size of the obstack chunk is 4096 by default. To customize the chunk size, use the macro obstack_chunk_size.

int obstack_chunk_size (struct obstack* obstack-ptr)

Note that this is actually a left value (C ++ contains troublesome reference to the left value, and the right value references rz ). As shown in myobstack, The obstack-ptr specifies which obstack is used. If you increase the chunk size properly, it will help improve efficiency. Reducing is not advantageous...

if (obstack_chunk_size (myobstack_ptr) < new-chunk-size)    obstack_chunk_size (myobstack_ptr) = new-chunk-size

 

Objects applied in the Obstack:

The most direct method is to use the aobstack_alloc function.

void * obstack_alloc (struct obstack *obstack-ptr, int size)

 

The call method is similar to that of malloc. The requested space is not initialized. If the chunk is filled with objects, obstack_alloc will automatically call obstack_chunk_alloc.

Struct obstack string_obstack ;/*.... initialization content .... */char * copystring (char * string) {size_t len = strlen (string) + 1; char * s = (char *) obstack_alloc (& string_obstack, len ); memcpy (s, string, len); return s ;}

 

If you want to initialize the object upon application, you must use obstack_copy or obstack_copy0.

Void * obstack_copy (struct obstack * obstack-ptr, void * address, int size) // use the address To Start copying the size data initialization, the memory size of the newly applied object is also sizevoid * obstack_copy0 (struct obstack * obstack-ptr, void * address, int size) // same as obstack_copy, but an additional null character is added at the end, it is convenient to copy a string ending with NULL.

 

 

Release objects in the Obstack:

Similarly, we use the obstack_free function.

void obstack_free  (struct obstack *obstack-ptr, void *object)

 

If the object is a null pointer, all objects are released, leaving an uninitialized obstack. Then, the obstack library Automatically releases the chunk. If you specify the object address, all objects after this object will be released. It is worth noting that if you want to release all objects while maintaining the obstack validity, you can specify the address of the first object.

obstack_free (obstack_ptr, first_object_allocated_ptr);

 

  

Objects that can increase the memory space:

Because the memory space of the obstack chunk is continuous, the object space can be set up step by step until the end. This technology is called the growing object. Although obstack can use growing object, you cannot use this technology for the applied object (the reason is that if there are objects after this object, it will cause a conflict)

Void obstack_blank (struct obstack * obstack-ptr, int size) // Add a growing objectvoid obstack_grow (struct obstack * obstack-ptr, void * data, int size) for initialization) // Add an initialized space, similar to obstack_copyvoid obstack_grow0 (struct obstack * obstack-ptr, void * data, int size) // obstack_grow is similar to obstack_copy, so obstack_grow0, who are you talking about? Void obstack_lgrow (struct obstack * obstack-ptr, charc) // Add a character (byte) at a time void obstack_ptr_grow (struct obstack * obstack-ptr, void * data) // Add a pointer at a time... Size: (sizeof (void *) void obstack_int_grow (struct obstack * obstack-ptr, int data) // Add an int type data at a time, size: sizeof (int)

 

The most important function in growing object is obstack_finish, because the final address of the growing object will be returned only after this function is called.

void *obstack_finish (struct obstrack *obstrack-ptr)

 

If you want to get the current growing object size, you can use obstack_object_size

Int obstack_object_size (struct obstack * obstrack-ptr) // it can only be used before obstack_finish. Otherwise, only 0 is returned.

 

If you want to cancel a growing object, you must end it before releasing it. Example:

obstack_free (obstack_ptr, obstack_finish (obstack_ptr))

 

When adding data, the above function checks whether there is sufficient space. If you only add a little bit of space, check this step is obviously redundant. We can omit this step for faster growing. Here is an additional function for growing object:

Int obstack_room (struct obstack * obstack-ptr) // returns the number of bytes that can be safely added.

 

To add other functions quickly, you only need to add the suffix _ fast to the previous growing object function (if you are not clear, you can refer to gnu c's introduction to this Part)

 

Obstack status:

Use the following functions to obtain the obstack status:

Void * obstack_base (struct obstack * obstack-ptr) // returns the hypothetical starting address of the growing object. Why is it assumed that, because if you increase too much and the current chunk space is insufficient, the obstack will create a new chunk, and the address will change. Void * obstack_next_free (struct obstack * obstack-ptr) // returns the address int obstack_object_size (struct obstack * obstack-ptr) of the first byte not occupied by the current chunk) // returns the size of the current growing object. Equivalent to: // obstack_next_free (obstack-ptr)-obstack_base (obstack-ptr)

 

 

Data Alignment in Obstack
int obstack_alignment_mask (struct obstack *obstack-ptr)

 

The macro is a left value. For function implementation, a mask is returned. The copy to him should also be a mask. The value of the mask must be one minus the Npower of 2. After conversion, the address must be a multiple of the Npower of 2. If you change the mask, it will only take effect the next time you apply for an object (the exception is the growing object: takes effect immediately. After you call obstack_finish, you will see the effect)

This article address http://www.cnblogs.com/san-fu-su/p/5739780.html

Related Article

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.