aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorValery Podrezov <valery.a.podrezov@intel.com>2007-02-02 11:48:21 -0500
committerLen Brown <len.brown@intel.com>2007-02-02 21:14:27 -0500
commit9bc75cff4919f9d947982d805aed89582a20d04d (patch)
treed07b8eb59b0dd6384f8fc5694113759ef7b8668e
parent4d0b4af958453afe871022e44abd57fac09baf67 (diff)
ACPICA: Eliminate control method 2-pass parse/execute.
Completed an AML interpreter performance enhancement for control method execution. Previously a 2-pass parse/execution, control methods are now completely parsed and executed in single pass. This improves overall interpreter performance by ~25%, reduces code size, and reduces CPU stack use. Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Alexey Starikovskiy <alexey.y.starikovskiy@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r--drivers/acpi/dispatcher/dsmethod.c50
-rw-r--r--drivers/acpi/parser/psloop.c2
-rw-r--r--drivers/acpi/parser/psxface.c114
3 files changed, 42 insertions, 124 deletions
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
index cf888add3191..aa60dca1f8aa 100644
--- a/drivers/acpi/dispatcher/dsmethod.c
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -327,7 +327,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
327 ACPI_FUNCTION_TRACE_PTR(ds_call_control_method, this_walk_state); 327 ACPI_FUNCTION_TRACE_PTR(ds_call_control_method, this_walk_state);
328 328
329 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, 329 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
330 "Execute method %p, currentstate=%p\n", 330 "Calling method %p, currentstate=%p\n",
331 this_walk_state->prev_op, this_walk_state)); 331 this_walk_state->prev_op, this_walk_state));
332 332
333 /* 333 /*
@@ -351,49 +351,7 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
351 return_ACPI_STATUS(status); 351 return_ACPI_STATUS(status);
352 } 352 }
353 353
354 /* 354 /* Begin method parse/execution. Create a new walk state */
355 * 1) Parse the method. All "normal" methods are parsed for each execution.
356 * Internal methods (_OSI, etc.) do not require parsing.
357 */
358 if (!(obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY)) {
359
360 /* Create a new walk state for the parse */
361
362 next_walk_state =
363 acpi_ds_create_walk_state(obj_desc->method.owner_id, op,
364 obj_desc, NULL);
365 if (!next_walk_state) {
366 status = AE_NO_MEMORY;
367 goto cleanup;
368 }
369
370 /* Create and init a parse tree root */
371
372 op = acpi_ps_create_scope_op();
373 if (!op) {
374 status = AE_NO_MEMORY;
375 goto cleanup;
376 }
377
378 status = acpi_ds_init_aml_walk(next_walk_state, op, method_node,
379 obj_desc->method.aml_start,
380 obj_desc->method.aml_length,
381 NULL, 1);
382 if (ACPI_FAILURE(status)) {
383 acpi_ps_delete_parse_tree(op);
384 goto cleanup;
385 }
386
387 /* Begin AML parse (deletes next_walk_state) */
388
389 status = acpi_ps_parse_aml(next_walk_state);
390 acpi_ps_delete_parse_tree(op);
391 if (ACPI_FAILURE(status)) {
392 goto cleanup;
393 }
394 }
395
396 /* 2) Begin method execution. Create a new walk state */
397 355
398 next_walk_state = acpi_ds_create_walk_state(obj_desc->method.owner_id, 356 next_walk_state = acpi_ds_create_walk_state(obj_desc->method.owner_id,
399 NULL, obj_desc, thread); 357 NULL, obj_desc, thread);
@@ -445,8 +403,8 @@ acpi_ds_call_control_method(struct acpi_thread_state *thread,
445 this_walk_state->num_operands = 0; 403 this_walk_state->num_operands = 0;
446 404
447 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, 405 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
448 "Starting nested execution, newstate=%p\n", 406 "**** Begin nested execution of [%4.4s] **** WalkState=%p\n",
449 next_walk_state)); 407 method_node->name.ascii, next_walk_state));
450 408
451 /* Invoke an internal method if necessary */ 409 /* Invoke an internal method if necessary */
452 410
diff --git a/drivers/acpi/parser/psloop.c b/drivers/acpi/parser/psloop.c
index a83be5201856..881687ca3154 100644
--- a/drivers/acpi/parser/psloop.c
+++ b/drivers/acpi/parser/psloop.c
@@ -226,7 +226,7 @@ acpi_ps_build_named_op(struct acpi_walk_state *walk_state,
226 return_ACPI_STATUS(status); 226 return_ACPI_STATUS(status);
227 } 227 }
228 228
229 if (!op) { 229 if (!*op) {
230 return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE); 230 return_ACPI_STATUS(AE_CTRL_PARSE_CONTINUE);
231 } 231 }
232 232
diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c
index 5d996c1140af..9069c697cf1d 100644
--- a/drivers/acpi/parser/psxface.c
+++ b/drivers/acpi/parser/psxface.c
@@ -54,8 +54,6 @@ static void acpi_ps_start_trace(struct acpi_evaluate_info *info);
54 54
55static void acpi_ps_stop_trace(struct acpi_evaluate_info *info); 55static void acpi_ps_stop_trace(struct acpi_evaluate_info *info);
56 56
57static acpi_status acpi_ps_execute_pass(struct acpi_evaluate_info *info);
58
59static void 57static void
60acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action); 58acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action);
61 59
@@ -215,6 +213,8 @@ static void acpi_ps_stop_trace(struct acpi_evaluate_info *info)
215acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) 213acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
216{ 214{
217 acpi_status status; 215 acpi_status status;
216 union acpi_parse_object *op;
217 struct acpi_walk_state *walk_state;
218 218
219 ACPI_FUNCTION_TRACE(ps_execute_method); 219 ACPI_FUNCTION_TRACE(ps_execute_method);
220 220
@@ -234,8 +234,7 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
234 } 234 }
235 235
236 /* 236 /*
237 * The caller "owns" the parameters, so give each one an extra 237 * The caller "owns" the parameters, so give each one an extra reference
238 * reference
239 */ 238 */
240 acpi_ps_update_parameter_list(info, REF_INCREMENT); 239 acpi_ps_update_parameter_list(info, REF_INCREMENT);
241 240
@@ -244,30 +243,50 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
244 acpi_ps_start_trace(info); 243 acpi_ps_start_trace(info);
245 244
246 /* 245 /*
247 * 1) Perform the first pass parse of the method to enter any 246 * Execute the method. Performs parse simultaneously
248 * named objects that it creates into the namespace
249 */ 247 */
250 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, 248 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
251 "**** Begin Method Parse **** Entry=%p obj=%p\n", 249 "**** Begin Method Parse/Execute [%4.4s] **** Node=%p Obj=%p\n",
252 info->resolved_node, info->obj_desc)); 250 info->resolved_node->name.ascii, info->resolved_node,
251 info->obj_desc));
253 252
254 info->pass_number = 1; 253 /* Create and init a Root Node */
255 status = acpi_ps_execute_pass(info); 254
256 if (ACPI_FAILURE(status)) { 255 op = acpi_ps_create_scope_op();
256 if (!op) {
257 status = AE_NO_MEMORY;
257 goto cleanup; 258 goto cleanup;
258 } 259 }
259 260
260 /* 261 /* Create and initialize a new walk state */
261 * 2) Execute the method. Performs second pass parse simultaneously
262 */
263 ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
264 "**** Begin Method Execution **** Entry=%p obj=%p\n",
265 info->resolved_node, info->obj_desc));
266 262
267 info->pass_number = 3; 263 info->pass_number = 3;
268 status = acpi_ps_execute_pass(info); 264 walk_state =
265 acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL,
266 NULL, NULL);
267 if (!walk_state) {
268 status = AE_NO_MEMORY;
269 goto cleanup;
270 }
271
272 status = acpi_ds_init_aml_walk(walk_state, op, info->resolved_node,
273 info->obj_desc->method.aml_start,
274 info->obj_desc->method.aml_length, info,
275 info->pass_number);
276 if (ACPI_FAILURE(status)) {
277 acpi_ds_delete_walk_state(walk_state);
278 goto cleanup;
279 }
280
281 /* Parse the AML */
282
283 status = acpi_ps_parse_aml(walk_state);
284
285 /* walk_state was deleted by parse_aml */
269 286
270 cleanup: 287 cleanup:
288 acpi_ps_delete_parse_tree(op);
289
271 /* End optional tracing */ 290 /* End optional tracing */
272 291
273 acpi_ps_stop_trace(info); 292 acpi_ps_stop_trace(info);
@@ -330,62 +349,3 @@ acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action)
330 } 349 }
331 } 350 }
332} 351}
333
334/*******************************************************************************
335 *
336 * FUNCTION: acpi_ps_execute_pass
337 *
338 * PARAMETERS: Info - See struct acpi_evaluate_info
339 * (Used: pass_number, Node, and obj_desc)
340 *
341 * RETURN: Status
342 *
343 * DESCRIPTION: Single AML pass: Parse or Execute a control method
344 *
345 ******************************************************************************/
346
347static acpi_status acpi_ps_execute_pass(struct acpi_evaluate_info *info)
348{
349 acpi_status status;
350 union acpi_parse_object *op;
351 struct acpi_walk_state *walk_state;
352
353 ACPI_FUNCTION_TRACE(ps_execute_pass);
354
355 /* Create and init a Root Node */
356
357 op = acpi_ps_create_scope_op();
358 if (!op) {
359 return_ACPI_STATUS(AE_NO_MEMORY);
360 }
361
362 /* Create and initialize a new walk state */
363
364 walk_state =
365 acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL,
366 NULL, NULL);
367 if (!walk_state) {
368 status = AE_NO_MEMORY;
369 goto cleanup;
370 }
371
372 status = acpi_ds_init_aml_walk(walk_state, op, info->resolved_node,
373 info->obj_desc->method.aml_start,
374 info->obj_desc->method.aml_length,
375 info->pass_number == 1 ? NULL : info,
376 info->pass_number);
377 if (ACPI_FAILURE(status)) {
378 acpi_ds_delete_walk_state(walk_state);
379 goto cleanup;
380 }
381
382 /* Parse the AML */
383
384 status = acpi_ps_parse_aml(walk_state);
385
386 /* Walk state was deleted by parse_aml */
387
388 cleanup:
389 acpi_ps_delete_parse_tree(op);
390 return_ACPI_STATUS(status);
391}