53 *varp = NULL; |
53 *varp = NULL; |
54 return UNKNOWN_ENUM; |
54 return UNKNOWN_ENUM; |
55 } |
55 } |
56 } |
56 } |
57 |
57 |
58 #define __BufferDebugDataIterator_case_t(TYPENAME) \ |
58 #define __Unpack_case_t(TYPENAME) \ |
59 case TYPENAME##_ENUM :\ |
59 case TYPENAME##_ENUM :\ |
60 *flags = ((__IEC_##TYPENAME##_t *)varp)->flags;\ |
60 *flags = ((__IEC_##TYPENAME##_t *)varp)->flags;\ |
61 *ptrvalue = &((__IEC_##TYPENAME##_t *)varp)->value;\ |
61 forced_value_p = *real_value_p = &((__IEC_##TYPENAME##_t *)varp)->value;\ |
62 break; |
62 break; |
63 |
63 |
64 #define __BufferDebugDataIterator_case_p(TYPENAME)\ |
64 #define __Unpack_case_p(TYPENAME)\ |
|
65 case TYPENAME##_O_ENUM :\ |
|
66 *flags = __IEC_OUTPUT_FLAG;\ |
65 case TYPENAME##_P_ENUM :\ |
67 case TYPENAME##_P_ENUM :\ |
66 case TYPENAME##_O_ENUM :\ |
68 *flags |= ((__IEC_##TYPENAME##_p *)varp)->flags;\ |
67 *flags = ((__IEC_##TYPENAME##_p *)varp)->flags;\ |
69 *real_value_p = ((__IEC_##TYPENAME##_p *)varp)->value;\ |
68 if (*flags & __IEC_FORCE_FLAG)\ |
70 forced_value_p = &((__IEC_##TYPENAME##_p *)varp)->fvalue;\ |
69 *ptrvalue = &((__IEC_##TYPENAME##_p *)varp)->fvalue;\ |
71 break; |
70 else\ |
72 |
71 *ptrvalue = ((__IEC_##TYPENAME##_p *)varp)->value;\ |
73 void* UnpackVar(void* varp, __IEC_types_enum vartype, void **real_value_p, char *flags) |
72 break; |
74 { |
73 |
75 void *forced_value_p = NULL; |
74 void UnpackVar(void* varp, __IEC_types_enum vartype, void **ptrvalue, char *flags) |
76 *flags = 0; |
75 { |
|
76 /* find data to copy*/ |
77 /* find data to copy*/ |
77 switch(vartype){ |
78 switch(vartype){ |
78 ANY(__BufferDebugDataIterator_case_t) |
79 ANY(__Unpack_case_t) |
79 ANY(__BufferDebugDataIterator_case_p) |
80 ANY(__Unpack_case_p) |
80 default: |
81 default: |
81 break; |
82 break; |
82 } |
83 } |
|
84 if (*flags & __IEC_FORCE_FLAG) |
|
85 return forced_value_p; |
|
86 return *real_value_p; |
83 } |
87 } |
84 |
88 |
85 void Remind(unsigned int offset, unsigned int count, void * p); |
89 void Remind(unsigned int offset, unsigned int count, void * p); |
86 |
90 |
87 void RemindIterator(void* varp, __IEC_types_enum vartype) |
91 void RemindIterator(void* varp, __IEC_types_enum vartype) |
88 { |
92 { |
89 void *ptrvalue = NULL; |
93 void *real_value_p = NULL; |
90 char flags = 0; |
94 char flags = 0; |
91 UnpackVar(varp, vartype, &ptrvalue, &flags); |
95 UnpackVar(varp, vartype, &real_value_p, &flags); |
92 |
96 |
93 if(flags & __IEC_RETAIN_FLAG){ |
97 if(flags & __IEC_RETAIN_FLAG){ |
94 USINT size = __get_type_enum_size(vartype); |
98 USINT size = __get_type_enum_size(vartype); |
95 /* compute next cursor positon*/ |
99 /* compute next cursor positon*/ |
96 unsigned int next_retain_offset = retain_offset + size; |
100 unsigned int next_retain_offset = retain_offset + size; |
97 /* if buffer not full */ |
101 /* if buffer not full */ |
98 Remind(retain_offset, size, ptrvalue); |
102 Remind(retain_offset, size, real_value_p); |
99 /* increment cursor according size*/ |
103 /* increment cursor according size*/ |
100 retain_offset = next_retain_offset; |
104 retain_offset = next_retain_offset; |
101 } |
105 } |
102 } |
106 } |
103 |
107 |
127 |
131 |
128 void __retrieve_debug(void) |
132 void __retrieve_debug(void) |
129 { |
133 { |
130 } |
134 } |
131 |
135 |
132 void DoDebug(void *ptrvalue, char flags, USINT size) |
|
133 { |
|
134 /* compute next cursor positon*/ |
|
135 char* next_cursor = buffer_cursor + size; |
|
136 /* if buffer not full */ |
|
137 if(next_cursor <= debug_buffer + BUFFER_SIZE) |
|
138 { |
|
139 /* copy data to the buffer */ |
|
140 memcpy(buffer_cursor, ptrvalue, size); |
|
141 /* increment cursor according size*/ |
|
142 buffer_cursor = next_cursor; |
|
143 }else{ |
|
144 /*TODO : signal overflow*/ |
|
145 } |
|
146 } |
|
147 |
136 |
148 void Retain(unsigned int offset, unsigned int count, void * p); |
137 void Retain(unsigned int offset, unsigned int count, void * p); |
149 void DoRetain(void *ptrvalue, char flags, USINT size){ |
138 |
150 /* compute next cursor positon*/ |
139 inline void BufferIterator(void* varp, __IEC_types_enum vartype, int do_debug) |
151 unsigned int next_retain_offset = retain_offset + size; |
140 { |
152 /* if buffer not full */ |
141 void *real_value_p = NULL; |
153 Retain(retain_offset, size, ptrvalue); |
142 void *visible_value_p = NULL; |
154 /* increment cursor according size*/ |
|
155 retain_offset = next_retain_offset; |
|
156 } |
|
157 |
|
158 void BufferDebugDataIterator(void* varp, __IEC_types_enum vartype) |
|
159 { |
|
160 void *ptrvalue = NULL; |
|
161 char flags = 0; |
143 char flags = 0; |
162 UnpackVar(varp, vartype, &ptrvalue, &flags); |
144 |
163 /* For optimization purpose we do retain and debug in the same pass */ |
145 visible_value_p = UnpackVar(varp, vartype, &real_value_p, &flags); |
164 if(flags & (__IEC_DEBUG_FLAG | __IEC_RETAIN_FLAG)){ |
146 |
|
147 if(flags & ( __IEC_DEBUG_FLAG | __IEC_RETAIN_FLAG)){ |
165 USINT size = __get_type_enum_size(vartype); |
148 USINT size = __get_type_enum_size(vartype); |
166 if(flags & __IEC_DEBUG_FLAG){ |
149 if(flags & __IEC_DEBUG_FLAG){ |
167 DoDebug(ptrvalue, flags, size); |
150 /* copy visible variable to buffer */; |
|
151 if(do_debug){ |
|
152 /* compute next cursor positon. |
|
153 No need to check overflow, as BUFFER_SIZE |
|
154 is computed large enough */ |
|
155 char* next_cursor = buffer_cursor + size; |
|
156 /* copy data to the buffer */ |
|
157 memcpy(buffer_cursor, visible_value_p, size); |
|
158 /* increment cursor according size*/ |
|
159 buffer_cursor = next_cursor; |
|
160 } |
|
161 /* re-force real value of outputs (M and Q)*/ |
|
162 if(flags & (__IEC_FORCE_FLAG | __IEC_OUTPUT_FLAG)){ |
|
163 memcpy(real_value_p, visible_value_p, size); |
|
164 } |
168 } |
165 } |
169 if(flags & __IEC_RETAIN_FLAG){ |
166 if(flags & __IEC_RETAIN_FLAG){ |
170 DoRetain(ptrvalue, flags, size); |
167 /* compute next cursor positon*/ |
|
168 unsigned int next_retain_offset = retain_offset + size; |
|
169 /* if buffer not full */ |
|
170 Retain(retain_offset, size, real_value_p); |
|
171 /* increment cursor according size*/ |
|
172 retain_offset = next_retain_offset; |
171 } |
173 } |
172 } |
174 } |
173 } |
175 } |
174 |
176 |
175 void RetainIterator(void* varp, __IEC_types_enum vartype) |
177 void DebugIterator(void* varp, __IEC_types_enum vartype){ |
176 { |
178 BufferIterator(varp, vartype, 1); |
177 void *ptrvalue = NULL; |
179 } |
178 char flags = 0; |
180 |
179 UnpackVar(varp, vartype, &ptrvalue, &flags); |
181 void RetainIterator(void* varp, __IEC_types_enum vartype){ |
180 |
182 BufferIterator(varp, vartype, 0); |
181 if(flags & __IEC_RETAIN_FLAG){ |
|
182 USINT size = __get_type_enum_size(vartype); |
|
183 DoRetain(ptrvalue, flags, size); |
|
184 } |
|
185 } |
183 } |
186 |
184 |
187 extern int TryEnterDebugSection(void); |
185 extern int TryEnterDebugSection(void); |
188 extern long AtomicCompareExchange(long*, long, long); |
186 extern long AtomicCompareExchange(long*, long, long); |
189 extern void LeaveDebugSection(void); |
187 extern void LeaveDebugSection(void); |