Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
soc:2009:lynusvaz:journal:week10 [2009/07/31 10:00] lynusvaz |
soc:2009:lynusvaz:journal:week10 [2009/08/02 10:50] (current) lynusvaz |
||
---|---|---|---|
Line 19: | Line 19: | ||
2377 95 2 2474 9aa bin/comboot_call.o | 2377 95 2 2474 9aa bin/comboot_call.o | ||
84571 11236 139798 235605 39855 (TOTALS) | 84571 11236 139798 235605 39855 (TOTALS) | ||
- | And the bin/rtl8139.rom has grown from 55808 to 57344B | + | And the bin/rtl8139.rom has grown from 55808 to 57344B. Latest commit in the [[http://git.etherboot.org/?p=people/lynusvaz/gpxe.git;a=shortlog;h=refs/heads/scripting_test|scripting_test]] branch: [[http://git.etherboot.org/?p=people/lynusvaz/gpxe.git;a=commit;h=d6f7017ac5827009d21648b079538fb5eeaed002|Arithmetic parser]] |
+ | |||
+ | August 1: Weekly meeting today. Today's topic was getting the patches merged into gPXE. Had a discussion with mcb30 on the generic stack implementation. The stack and struct string idea was started to let the parser work without having to deal with issues like memory allocation, and also to help other modules that will use stacks. The current implementation is just a wrapper around an array to push and pop elements. The disadvantage is that since the array is fixed, the stack has a limited size. mcb30 recommended that I use the list_head structure and macros to implement an unbounded stack, that can accomodate as many elements as required. The basic skeleton is: | ||
+ | struct stack { | ||
+ | struct list_head list; | ||
+ | }; | ||
+ | |||
+ | struct stack_element { | ||
+ | struct list_head list; | ||
+ | char data[0]; | ||
+ | }; | ||
+ | |||
+ | #define STACK( _type ) \ | ||
+ | union { \ | ||
+ | struct stack stack; \ | ||
+ | _type type[0]; \ | ||
+ | } | ||
+ | |||
+ | #define STACK_PUSH( _stack, _data_len ) \ | ||
+ | ( ( typeof ( &(_stack)->type[0] ) ) \ | ||
+ | stack_push ( (_stack)->stack, _data_len ) ) | ||
+ | |||
+ | #define STACK_POP( _item ) \ | ||
+ | stack_pop ( _item ); | ||
+ | |||
+ | void * stack_push ( struct stack stack, size_t data_len ) { | ||
+ | struct stack_element *element; | ||
+ | element = malloc ( sizeof ( *element ) + data_len ); | ||
+ | |||
+ | if ( ! element ) | ||
+ | return NULL; | ||
+ | |||
+ | list_add_tail ( &element->list, &stack->list ); | ||
+ | return &element->data; | ||
+ | } | ||
+ | |||
+ | void stack_pop ( void *data ) { | ||
+ | struct stack_element *element = | ||
+ | container_of ( data, struct stack_element, data ); | ||
+ | list_del ( &element->list ); | ||
+ | free ( element ); | ||
+ | } | ||
+ | |||
+ | August 2: Worked on the stack today. A few modifications to yesterday's ideas: | ||
+ | * Added a stack_for_each macro to help iteration over the stack. | ||
+ | * I had some problems with passing the stack to a function. The type information is held in the union, but actually passing the union to a function needs to have the data type clearly defined. So, I passed only a pointer to a struct stack, which removed the type information. | ||
+ | * Hence, I made the STACK_PUSH macro take the type of the new element, and call the push_stack function with the sizeof(type) argument. | ||
+ | |||
+ | #define PUSH_STACK( _stack, _type ) ( _type * ) stack_push ( _stack, sizeof ( _type ) ) | ||
+ | |||
+ | This will retain the type information without the union, but it requires the user to know the type of element being pushed, and this may lead to mistakes. This stack implementation seems to add around 135B to the uncompressed code. | ||