Heinrich Schuchardt | 9757cae | 2023-10-31 14:55:51 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
| 2 | |
| 3 | #include <asm/setjmp.h> |
| 4 | |
| 5 | /** |
| 6 | * struct resume_data - data for resume after interrupt |
| 7 | */ |
| 8 | struct resume_data { |
| 9 | /** @jump: longjmp buffer */ |
| 10 | jmp_buf jump; |
| 11 | /** @code: exception code */ |
| 12 | ulong code; |
| 13 | }; |
| 14 | |
| 15 | /** |
| 16 | * set_resume() - set longjmp buffer for resuming after exception |
| 17 | * |
| 18 | * By calling this function it is possible to use a long jump to catch an |
| 19 | * exception. The caller sets the long jump buffer with set_resume() and then |
| 20 | * executes setjmp(). If an exception occurs, the code will return to the |
| 21 | * setjmp caller(). The exception code will be returned in @data->code. |
| 22 | * |
| 23 | * After the critical operation call set_resume(NULL) so that an exception in |
| 24 | * another part of the code will not accidently invoke the long jump. |
| 25 | * |
| 26 | * .. code-block:: c |
| 27 | * |
| 28 | * // This example shows how to use set_resume(). |
| 29 | * |
| 30 | * struct resume_data resume; |
| 31 | * int ret; |
| 32 | * |
| 33 | * set_resume(&resume); |
| 34 | * ret = setjmp(resume.jump); |
| 35 | * if (ret) { |
| 36 | * printf("An exception %ld occurred\n", resume.code); |
| 37 | * } else { |
| 38 | * // Do what might raise an exception here. |
| 39 | * } |
| 40 | * set_resume(NULL); |
| 41 | * |
| 42 | * @data: pointer to structure with longjmp address |
| 43 | * Return: 0 before an exception, 1 after an exception occurred |
| 44 | */ |
| 45 | void set_resume(struct resume_data *data); |