├── LICENSE ├── README.md ├── arch ├── linux │ ├── cpu_thread.c │ └── cpu_thread.h ├── riscv │ ├── cpu_thread.c │ └── cpu_thread.h └── template │ └── cpu_thread.h ├── kernel ├── critical.h ├── event.c ├── event.h ├── list.h ├── mailbox.c ├── mailbox.h ├── mutex.c ├── mutex.h ├── os_assert.h ├── semaphore.c ├── semaphore.h ├── thread.c └── thread.h └── testcases ├── test.h ├── test_basic0.c ├── test_basic1.c ├── test_basic2.c ├── test_join0.c ├── test_join1.c ├── test_kill0.c ├── test_mtx0.c ├── test_mtx1.c ├── test_sem0.c ├── test_sem1.c ├── test_sem2.c └── test_torture0.c /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # librtos 2 | Very basic real time operating system for embedded systems... 3 | -------------------------------------------------------------------------------- /arch/linux/cpu_thread.c: -------------------------------------------------------------------------------- 1 | #include "cpu_thread.h" 2 | #include "kernel/thread.h" 3 | #include "kernel/os_assert.h" 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | //----------------------------------------------------------------- 21 | // Locals: 22 | //----------------------------------------------------------------- 23 | static volatile uint32_t _in_interrupt = 0; 24 | static int _initial_switch = 0; 25 | static sigset_t _sig_alarm; 26 | static ucontext_t _initial_ctx; 27 | 28 | #define DISABLE_TICK() sigprocmask(SIG_BLOCK, &_sig_alarm, NULL); 29 | #define ENABLE_TICK() sigprocmask(SIG_UNBLOCK, &_sig_alarm, NULL); 30 | 31 | //----------------------------------------------------------------- 32 | // cpu_thread_init_tcb: 33 | //----------------------------------------------------------------- 34 | void cpu_thread_init_tcb(struct cpu_tcb *tcb, void (*func)(void *), void *funcArg, void *stack, uint32_t stack_size) 35 | { 36 | // Not required, but interesting.. 37 | tcb->stack_size = stack_size; 38 | 39 | // Critical depth = 0 so not in critical section (ints enabled) 40 | tcb->critical_depth = 0; 41 | 42 | // Create thread context 43 | getcontext (&tcb->ctx); 44 | tcb->ctx.uc_link = &_initial_ctx; 45 | tcb->ctx.uc_stack.ss_sp = stack; 46 | tcb->ctx.uc_stack.ss_size = stack_size * sizeof (uint32_t); 47 | makecontext (&tcb->ctx, (void (*) (void)) func, 1, funcArg); 48 | } 49 | //----------------------------------------------------------------- 50 | // cpu_critical_start: Force interrupts to be disabled 51 | //----------------------------------------------------------------- 52 | int cpu_critical_start(void) 53 | { 54 | struct thread* thread = thread_current(); 55 | 56 | // Don't do anything to the interrupt status if already within IRQ 57 | if (_in_interrupt || thread == NULL) 58 | return 0; 59 | 60 | // Disable interrupts 61 | DISABLE_TICK(); 62 | 63 | // Increase critical depth 64 | thread->tcb.critical_depth++; 65 | 66 | return (int)0; 67 | } 68 | //----------------------------------------------------------------- 69 | // cpu_critical_end: Restore interrupt enable state 70 | //----------------------------------------------------------------- 71 | void cpu_critical_end(int cr) 72 | { 73 | struct thread* thread = thread_current(); 74 | 75 | // Don't do anything to the interrupt status if already within IRQ 76 | if (_in_interrupt || thread == NULL) 77 | return ; 78 | 79 | OS_ASSERT(thread->tcb.critical_depth > 0); 80 | OS_ASSERT(thread->tcb.critical_depth < 255); 81 | 82 | // Decrement critical depth 83 | thread->tcb.critical_depth--; 84 | 85 | // End of critical section? 86 | if (thread->tcb.critical_depth == 0) 87 | { 88 | // Manually re-enable IRQ 89 | ENABLE_TICK(); 90 | } 91 | 92 | return; 93 | } 94 | //----------------------------------------------------------------- 95 | // cpu_context_switch: 96 | //----------------------------------------------------------------- 97 | void cpu_context_switch( void ) 98 | { 99 | struct thread* suspend_thread; 100 | struct thread* resume_thread; 101 | 102 | // Check that this not occuring recursively! 103 | OS_ASSERT(!_in_interrupt); 104 | _in_interrupt = 1; 105 | 106 | // Suspend current thread 107 | suspend_thread = thread_current(); 108 | if (_initial_switch) 109 | { 110 | suspend_thread = NULL; 111 | _initial_switch = 0; 112 | } 113 | 114 | // Load new thread context 115 | thread_load_context(0); 116 | 117 | // Resume new thread 118 | resume_thread = thread_current(); 119 | _in_interrupt = 0; 120 | 121 | // Only suspend and resume if actually needed 122 | if (resume_thread != suspend_thread) 123 | { 124 | if (suspend_thread) 125 | swapcontext(&suspend_thread->tcb.ctx, &resume_thread->tcb.ctx); 126 | else 127 | setcontext(&resume_thread->tcb.ctx); 128 | } 129 | } 130 | //----------------------------------------------------------------- 131 | // cpu_context_switch_irq: 132 | //----------------------------------------------------------------- 133 | void cpu_context_switch_irq( void ) 134 | { 135 | // No need to do anything in this system as all interrupts 136 | // cause the kernel to run... 137 | OS_ASSERT(_in_interrupt); 138 | } 139 | //----------------------------------------------------------------- 140 | // cpu_tick: 141 | //----------------------------------------------------------------- 142 | static CRITICALFUNC void cpu_tick(int sig) 143 | { 144 | struct thread* suspend_thread; 145 | struct thread* resume_thread; 146 | 147 | // Check that this not occuring recursively! 148 | OS_ASSERT(!_in_interrupt); 149 | _in_interrupt = 1; 150 | 151 | // Suspend current thread 152 | suspend_thread = thread_current(); 153 | 154 | // Decrement thread sleep timers 155 | thread_tick(); 156 | 157 | // Load new thread context 158 | thread_load_context(1); 159 | 160 | // Resume new thread 161 | resume_thread = thread_current(); 162 | 163 | _in_interrupt = 0; 164 | 165 | // Only suspend and resume if actually needed 166 | if (resume_thread != suspend_thread) 167 | { 168 | if (suspend_thread) 169 | swapcontext(&suspend_thread->tcb.ctx, &resume_thread->tcb.ctx); 170 | else 171 | setcontext(&resume_thread->tcb.ctx); 172 | } 173 | } 174 | //----------------------------------------------------------------- 175 | // cpu_thread_start: 176 | //----------------------------------------------------------------- 177 | void cpu_thread_start( void ) 178 | { 179 | struct itimerval itimer, oitimer; 180 | struct sigaction sigtick; 181 | 182 | _initial_switch = 1; 183 | 184 | getcontext (&_initial_ctx); 185 | 186 | // Register tick handler 187 | memset(&sigtick, 0, sizeof(sigtick)); 188 | sigtick.sa_handler = cpu_tick; 189 | sigaction(SIGVTALRM, &sigtick, NULL); 190 | 191 | sigemptyset(&_sig_alarm); 192 | sigaddset(&_sig_alarm, SIGVTALRM); 193 | 194 | // Configure timer 195 | itimer.it_interval.tv_sec = 0; 196 | itimer.it_interval.tv_usec = 1 * 1000; 197 | itimer.it_value.tv_sec = itimer.it_interval.tv_sec; 198 | itimer.it_value.tv_usec = itimer.it_interval.tv_usec; 199 | setitimer(ITIMER_VIRTUAL, &itimer, NULL); 200 | 201 | // Switch to initial task 202 | cpu_context_switch(); 203 | while (1) 204 | ; 205 | } 206 | //----------------------------------------------------------------- 207 | // cpu_thread_assert: Assert handler 208 | //----------------------------------------------------------------- 209 | void cpu_thread_assert(const char *reason, const char *file, int line) 210 | { 211 | struct thread* thread; 212 | 213 | cpu_critical_start(); 214 | 215 | thread = thread_current(); 216 | if (thread) 217 | { 218 | printf("[%s] Assert failed: %s (%s:%d)\r\n", thread->name, reason, file, line); 219 | 220 | // Dump thread list 221 | thread_dump_list(printf); 222 | assert(0); 223 | } 224 | // Early assert 225 | else 226 | { 227 | printf("Assert failed: %s (%s:%d)\r\n", reason, file, line); 228 | assert(0); 229 | } 230 | } 231 | //----------------------------------------------------------------- 232 | // cpu_thread_stack_size: 233 | //----------------------------------------------------------------- 234 | int cpu_thread_stack_size(struct cpu_tcb * pCurrent) 235 | { 236 | return (int)pCurrent->stack_size; 237 | } 238 | //----------------------------------------------------------------- 239 | // cpu_thread_stack_free: 240 | //----------------------------------------------------------------- 241 | int cpu_thread_stack_free(struct cpu_tcb * pCurrent) 242 | { 243 | return (int)pCurrent->stack_size; 244 | } 245 | //----------------------------------------------------------------- 246 | // cpu_idle: CPU specific idle function 247 | //----------------------------------------------------------------- 248 | void cpu_idle(void) 249 | { 250 | // Do nothing 251 | } 252 | 253 | #ifdef INCLUDE_TEST_MAIN 254 | //----------------------------------------------------------------- 255 | // main: 256 | //----------------------------------------------------------------- 257 | #define APP_STACK_SIZE (1024*8) 258 | 259 | //----------------------------------------------------------------- 260 | // Locals: 261 | //----------------------------------------------------------------- 262 | THREAD_DECL(app, APP_STACK_SIZE); 263 | 264 | extern void* testcase(void * a); 265 | 266 | //----------------------------------------------------------------- 267 | // main: 268 | //----------------------------------------------------------------- 269 | int main(void) 270 | { 271 | // Setup the RTOS 272 | thread_kernel_init(); 273 | 274 | // Create init thread 275 | THREAD_INIT(app, "INIT", testcase, NULL, THREAD_MAX_PRIO - 1); 276 | 277 | // Start kernel 278 | thread_kernel_run(); 279 | 280 | // Kernel should never init 281 | OS_ASSERT(0); 282 | } 283 | #endif -------------------------------------------------------------------------------- /arch/linux/cpu_thread.h: -------------------------------------------------------------------------------- 1 | #ifndef __CPU_THREAD_H__ 2 | #define __CPU_THREAD_H__ 3 | 4 | #include 5 | #include 6 | 7 | //----------------------------------------------------------------- 8 | // Defines 9 | //----------------------------------------------------------------- 10 | #define STACK_CHK_BYTE 0xCAFEFEAD 11 | 12 | // Optional: Define gcc section linkage to relocate critical functions to faster memory 13 | #ifndef CRITICALFUNC 14 | #define CRITICALFUNC 15 | #endif 16 | 17 | //----------------------------------------------------------------- 18 | // Structures 19 | //----------------------------------------------------------------- 20 | 21 | // Task Control Block 22 | struct cpu_tcb 23 | { 24 | ucontext_t ctx; 25 | 26 | // Stack size 27 | uint32_t stack_size; 28 | 29 | // Critical section / Interrupt status 30 | uint32_t critical_depth; 31 | }; 32 | 33 | typedef uint64_t stk_t; 34 | 35 | //----------------------------------------------------------------- 36 | // Prototypes 37 | //----------------------------------------------------------------- 38 | 39 | // Initialise thread context 40 | void cpu_thread_init_tcb(struct cpu_tcb *tcb, void (*func)(void *), void *funcArg, void *stack, uint32_t stack_size ); 41 | 42 | // Start first thread switch 43 | void cpu_thread_start(void); 44 | 45 | // Force context switch 46 | void cpu_context_switch(void); 47 | 48 | // Force context switch (from IRQ) 49 | void cpu_context_switch_irq(void); 50 | 51 | // Critical section entry & exit 52 | int cpu_critical_start(void); 53 | void cpu_critical_end(int cr); 54 | 55 | // CPU specific idle function 56 | void cpu_idle(void); 57 | 58 | // Specified thread TCB's free stack entries count 59 | int cpu_thread_stack_free(struct cpu_tcb * pCurrent); 60 | 61 | // Specified thread TCB's total stack size 62 | int cpu_thread_stack_size(struct cpu_tcb * pCurrent); 63 | 64 | // CPU clocks/time measurement functions (optional, used if CONFIG_RTOS_MEASURE_THREAD_TIME defined) 65 | uint64_t cpu_timenow(void); 66 | int64_t cpu_timediff(uint64_t a, uint64_t b); 67 | 68 | // System specific assert handling function 69 | void cpu_thread_assert(const char *reason, const char *file, int line); 70 | 71 | #endif 72 | 73 | -------------------------------------------------------------------------------- /arch/riscv/cpu_thread.c: -------------------------------------------------------------------------------- 1 | #include "cpu_thread.h" 2 | #include "kernel/thread.h" 3 | #include "kernel/os_assert.h" 4 | 5 | #include "exception.h" 6 | #include "csr.h" 7 | #include "assert.h" 8 | #include "timer.h" 9 | 10 | //----------------------------------------------------------------- 11 | // Defines: 12 | //----------------------------------------------------------------- 13 | 14 | // Macro used to stop profiling functions being called 15 | #define NO_PROFILE __attribute__((__no_instrument_function__)) 16 | 17 | #define WEAK __attribute__((weak)) 18 | 19 | // Preempt rate 20 | #define TICK_RATE_HZ 1000 21 | 22 | //----------------------------------------------------------------- 23 | // Locals: 24 | //----------------------------------------------------------------- 25 | // Detect recursive interrupts (which are not supported) 26 | static volatile uint32_t _in_interrupt = 0; 27 | static fp_irq _platform_irq_cb = 0; 28 | 29 | //----------------------------------------------------------------- 30 | // cpu_thread_init_tcb: Initialise thread context 31 | //----------------------------------------------------------------- 32 | void cpu_thread_init_tcb(struct cpu_tcb *tcb, void (*func)(void *), void *funcArg, uint32_t *stack, uint32_t stack_size) 33 | { 34 | int i; 35 | 36 | OS_ASSERT(stack != NULL); 37 | 38 | tcb->stack_alloc = stack; 39 | tcb->stack_size = stack_size; 40 | 41 | // Set default check byte 42 | for (i=0;istack_size;i++) 43 | tcb->stack_alloc[i] = STACK_CHK_BYTE; 44 | 45 | tcb->ctx = exception_makecontext(stack, stack_size, func, funcArg); 46 | 47 | // Enable IRQ within this context 48 | context_irq_enable(tcb->ctx, 1); 49 | 50 | // Critical depth = 0 so not in critical section (ints enabled) 51 | tcb->critical_depth = 0; 52 | } 53 | //----------------------------------------------------------------- 54 | // cpu_critical_start: Force interrupts to be disabled 55 | //----------------------------------------------------------------- 56 | int NO_PROFILE cpu_critical_start(void) 57 | { 58 | struct thread* thread = thread_current(); 59 | 60 | // Don't do anything to the interrupt status if already within IRQ 61 | if (_in_interrupt || thread == NULL) 62 | return 0; 63 | 64 | // Disable interrupts 65 | csr_clr_irq_enable(); 66 | 67 | // Increase critical depth 68 | thread->tcb.critical_depth++; 69 | 70 | return (int)0; 71 | } 72 | //----------------------------------------------------------------- 73 | // cpu_critical_end: Restore interrupt enable state 74 | //----------------------------------------------------------------- 75 | void NO_PROFILE cpu_critical_end(int cr) 76 | { 77 | struct thread* thread = thread_current(); 78 | 79 | // Don't do anything to the interrupt status if already within IRQ 80 | if (_in_interrupt || thread == NULL) 81 | return ; 82 | 83 | OS_ASSERT(thread->tcb.critical_depth > 0); 84 | OS_ASSERT(thread->tcb.critical_depth < 255); 85 | 86 | // Decrement critical depth 87 | thread->tcb.critical_depth--; 88 | 89 | // End of critical section? 90 | if (thread->tcb.critical_depth == 0) 91 | { 92 | // Manually re-enable IRQ 93 | csr_set_irq_enable(); 94 | } 95 | 96 | return; 97 | } 98 | //----------------------------------------------------------------- 99 | // cpu_context_switch: Force context switch 100 | //----------------------------------------------------------------- 101 | void cpu_context_switch( void ) 102 | { 103 | OS_ASSERT(!_in_interrupt); 104 | 105 | // Cause context switch 106 | exception_syscall(0); 107 | } 108 | //----------------------------------------------------------------- 109 | // cpu_context_switch_irq: Force context switch (from IRQ) 110 | //----------------------------------------------------------------- 111 | void cpu_context_switch_irq( void ) 112 | { 113 | // No need to do anything in this system as all interrupts 114 | // cause the kernel to run... 115 | OS_ASSERT(_in_interrupt); 116 | } 117 | //----------------------------------------------------------------- 118 | // cpu_syscall: Handle system call exception 119 | //----------------------------------------------------------------- 120 | static CRITICALFUNC struct irq_context * cpu_syscall(struct irq_context *ctx) 121 | { 122 | struct thread* thread; 123 | 124 | // Check that this not occuring recursively! 125 | OS_ASSERT(!_in_interrupt); 126 | _in_interrupt = 1; 127 | 128 | // Record stack pointer in current task TCB 129 | thread = thread_current(); 130 | if (thread) 131 | { 132 | // Stack range check 133 | OS_ASSERT(((uint32_t)ctx->reg[REG_SP] >= (uint32_t)thread->tcb.stack_alloc) && 134 | ((uint32_t)ctx->reg[REG_SP] < (uint32_t)(&thread->tcb.stack_alloc[thread->tcb.stack_size]))); 135 | 136 | thread->tcb.ctx = ctx; 137 | 138 | // Try and detect stack overflow 139 | OS_ASSERT(thread->tcb.stack_alloc[0] == STACK_CHK_BYTE); 140 | } 141 | 142 | // Load new thread context 143 | thread_load_context(0); 144 | 145 | // Get stack frame of new thread 146 | thread = thread_current(); 147 | ctx = (uint32_t *)thread->tcb.ctx; 148 | 149 | // Try and detect stack overflow 150 | OS_ASSERT(thread->tcb.stack_alloc[0] == STACK_CHK_BYTE); 151 | 152 | _in_interrupt = 0; 153 | 154 | return ctx; 155 | } 156 | //----------------------------------------------------------------- 157 | // cpu_timer_irq: Handle (timer) interrupt exception 158 | //----------------------------------------------------------------- 159 | static CRITICALFUNC struct irq_context * cpu_timer_irq(struct irq_context *ctx) 160 | { 161 | struct thread* thread; 162 | 163 | // Check that this not occuring recursively! 164 | OS_ASSERT(!_in_interrupt); 165 | _in_interrupt = 1; 166 | 167 | // Record stack pointer in current task TCB 168 | thread = thread_current(); 169 | if (thread) 170 | { 171 | // Stack range check 172 | OS_ASSERT(((uint32_t)ctx->reg[REG_SP] >= (uint32_t)thread->tcb.stack_alloc) && 173 | ((uint32_t)ctx->reg[REG_SP] < (uint32_t)(&thread->tcb.stack_alloc[thread->tcb.stack_size]))); 174 | 175 | thread->tcb.ctx = ctx; 176 | 177 | // Try and detect stack overflow 178 | OS_ASSERT(thread->tcb.stack_alloc[0] == STACK_CHK_BYTE); 179 | } 180 | 181 | // Handle thread scheduling 182 | thread_tick(); 183 | 184 | // Reset timer (ack pending interrupt) 185 | timer_set_mtimecmp(timer_get_mtime() + (MCU_CLK/TICK_RATE_HZ)); 186 | csr_clear(mip, SR_IP_MTIP); 187 | csr_set(mie, SR_IP_MTIP); 188 | 189 | // Load new thread context 190 | thread_load_context(1); 191 | 192 | // Get stack frame of new thread 193 | thread = thread_current(); 194 | ctx = (uint32_t *)thread->tcb.ctx; 195 | 196 | // Try and detect stack overflow 197 | OS_ASSERT(thread->tcb.stack_alloc[0] == STACK_CHK_BYTE); 198 | 199 | _in_interrupt = 0; 200 | 201 | return ctx; 202 | } 203 | //----------------------------------------------------------------- 204 | // cpu_irq_wrapper: Handle (external) interrupt exception 205 | //----------------------------------------------------------------- 206 | static CRITICALFUNC struct irq_context * cpu_irq_wrapper(struct irq_context *ctx) 207 | { 208 | OS_ASSERT(_platform_irq_cb); 209 | 210 | // Check that this not occuring recursively! 211 | OS_ASSERT(!_in_interrupt); 212 | _in_interrupt = 1; 213 | ctx = _platform_irq_cb(ctx); 214 | _in_interrupt = 0; 215 | 216 | return ctx; 217 | } 218 | //----------------------------------------------------------------- 219 | // cpu_thread_start: 220 | //----------------------------------------------------------------- 221 | void cpu_thread_start( void ) 222 | { 223 | // Fault handlers 224 | exception_set_syscall_handler(cpu_syscall); 225 | exception_set_timer_handler(cpu_timer_irq); 226 | 227 | _platform_irq_cb = exception_get_irq_handler(); 228 | exception_set_irq_handler(cpu_irq_wrapper); 229 | 230 | // Make sure current IRQ enable is disabled 231 | csr_clr_irq_enable(); 232 | 233 | // Enable timer IRQ source (global IRQ still disabled) 234 | timer_set_mtimecmp(timer_get_mtime() + (MCU_CLK/TICK_RATE_HZ)); 235 | csr_set(mie, SR_IP_MTIP); 236 | 237 | // Run the scheduler to pick the highest prio thread 238 | thread_load_context(0); 239 | 240 | // Return to context of initial thread 241 | exception_return(thread_current()->tcb.ctx); 242 | } 243 | //----------------------------------------------------------------- 244 | // cpu_thread_assert: Assert handler 245 | //----------------------------------------------------------------- 246 | void cpu_thread_assert(const char *reason, const char *file, int line) 247 | { 248 | struct thread* thread; 249 | 250 | cpu_critical_start(); 251 | 252 | thread = thread_current(); 253 | if (thread) 254 | { 255 | printf("[%s] Assert failed: %s (%s:%d)\r\n", thread->name, reason, file, line); 256 | 257 | // Dump thread list 258 | thread_dump_list(printf); 259 | 260 | { 261 | uint32_t *registers = (uint32_t *)thread->tcb.ctx; 262 | int i; 263 | 264 | printf("Frame:\n"); 265 | printf(" Critical Depth 0x%x\n", thread->tcb.critical_depth); 266 | printf(" PC 0x%x\n", thread->tcb.ctx->pc); 267 | printf(" SR 0x%x\n", thread->tcb.ctx->status); 268 | 269 | for (i=0;i<32;i++) 270 | printf(" R%x = 0x%x\n", i, thread->tcb.ctx->reg[i]); 271 | } 272 | 273 | while (1) 274 | ; 275 | } 276 | // Early assert 277 | else 278 | { 279 | printf("Assert failed: %s (%s:%d)\r\n", reason, file, line); 280 | while (1) 281 | ; 282 | } 283 | } 284 | //----------------------------------------------------------------- 285 | // cpu_thread_stack_size: 286 | //----------------------------------------------------------------- 287 | int cpu_thread_stack_size(struct cpu_tcb * pCurrent) 288 | { 289 | return (int)pCurrent->stack_size; 290 | } 291 | //----------------------------------------------------------------- 292 | // cpu_thread_stack_free: 293 | //----------------------------------------------------------------- 294 | int cpu_thread_stack_free(struct cpu_tcb * pCurrent) 295 | { 296 | int i; 297 | int free = 0; 298 | 299 | for (i=0;istack_size;i++) 300 | { 301 | if (pCurrent->stack_alloc[i] != STACK_CHK_BYTE) 302 | break; 303 | else 304 | free++; 305 | } 306 | 307 | return free; 308 | } 309 | //----------------------------------------------------------------- 310 | // cpu_idle: CPU specific idle function 311 | //----------------------------------------------------------------- 312 | WEAK void cpu_idle(void) 313 | { 314 | // Do nothing 315 | } 316 | #ifdef INCLUDE_TEST_MAIN 317 | //----------------------------------------------------------------- 318 | // main: 319 | //----------------------------------------------------------------- 320 | #define APP_STACK_SIZE (1024) 321 | 322 | //----------------------------------------------------------------- 323 | // Locals: 324 | //----------------------------------------------------------------- 325 | THREAD_DECL(app, APP_STACK_SIZE); 326 | 327 | extern void* testcase(void * a); 328 | 329 | //----------------------------------------------------------------- 330 | // main: 331 | //----------------------------------------------------------------- 332 | int main(void) 333 | { 334 | // Setup the RTOS 335 | thread_kernel_init(); 336 | 337 | // Create init thread 338 | THREAD_INIT(app, "INIT", testcase, NULL, THREAD_MAX_PRIO - 1); 339 | 340 | // Start kernel 341 | thread_kernel_run(); 342 | 343 | // Kernel should never init 344 | OS_ASSERT(0); 345 | } 346 | #endif 347 | -------------------------------------------------------------------------------- /arch/riscv/cpu_thread.h: -------------------------------------------------------------------------------- 1 | #ifndef __CPU_THREAD_H__ 2 | #define __CPU_THREAD_H__ 3 | 4 | #include "exception.h" 5 | 6 | //----------------------------------------------------------------- 7 | // Defines 8 | //----------------------------------------------------------------- 9 | #define STACK_CHK_BYTE 0xCAFEFEAD 10 | 11 | // Optional: Define gcc section linkage to relocate critical functions to faster memory 12 | #ifndef CRITICALFUNC 13 | #define CRITICALFUNC 14 | #endif 15 | 16 | //----------------------------------------------------------------- 17 | // Structures 18 | //----------------------------------------------------------------- 19 | 20 | // Task Control Block 21 | struct cpu_tcb 22 | { 23 | volatile struct irq_context *ctx; 24 | 25 | // Stack end pointer 26 | uint32_t *stack_alloc; 27 | 28 | // Stack size 29 | uint32_t stack_size; 30 | 31 | // Critical section / Interrupt status 32 | uint32_t critical_depth; 33 | }; 34 | 35 | typedef uint32_t stk_t; 36 | 37 | //----------------------------------------------------------------- 38 | // Prototypes 39 | //----------------------------------------------------------------- 40 | 41 | // Initialise thread context 42 | void cpu_thread_init_tcb(struct cpu_tcb *tcb, void (*func)(void *), void *funcArg, uint32_t *stack, uint32_t stack_size ); 43 | 44 | // Start first thread switch 45 | void cpu_thread_start(void); 46 | 47 | // Force context switch 48 | void cpu_context_switch(void); 49 | 50 | // Force context switch (from IRQ) 51 | void cpu_context_switch_irq(void); 52 | 53 | // Critical section entry & exit 54 | int cpu_critical_start(void); 55 | void cpu_critical_end(int cr); 56 | 57 | // CPU specific idle function 58 | void cpu_idle(void); 59 | 60 | // Specified thread TCB's free stack entries count 61 | int cpu_thread_stack_free(struct cpu_tcb * pCurrent); 62 | 63 | // Specified thread TCB's total stack size 64 | int cpu_thread_stack_size(struct cpu_tcb * pCurrent); 65 | 66 | // CPU clocks/time measurement functions (optional, used if CONFIG_RTOS_MEASURE_THREAD_TIME defined) 67 | uint64_t cpu_timenow(void); 68 | int64_t cpu_timediff(uint64_t a, uint64_t b); 69 | 70 | // System specific assert handling function 71 | void cpu_thread_assert(const char *reason, const char *file, int line); 72 | 73 | #endif 74 | 75 | -------------------------------------------------------------------------------- /arch/template/cpu_thread.h: -------------------------------------------------------------------------------- 1 | #ifndef __CPU_THREAD_H__ 2 | #define __CPU_THREAD_H__ 3 | 4 | #include 5 | 6 | //----------------------------------------------------------------- 7 | // Defines 8 | //----------------------------------------------------------------- 9 | #define STACK_CHK_BYTE 0xCAFEFEAD 10 | 11 | // Optional: Define gcc section linkage to relocate critical functions to faster memory 12 | #ifndef CRITICALFUNC 13 | #define CRITICALFUNC 14 | #endif 15 | 16 | //----------------------------------------------------------------- 17 | // Structures 18 | //----------------------------------------------------------------- 19 | 20 | // Task Control Block 21 | struct cpu_tcb 22 | { 23 | ... thread context state ... 24 | 25 | // Stack end pointer 26 | uint32_t *stack_alloc; 27 | 28 | // Stack size 29 | uint32_t stack_size; 30 | 31 | // Critical section / Interrupt status 32 | uint32_t critical_depth; 33 | }; 34 | 35 | typedef uint32_t stk_t; 36 | 37 | //----------------------------------------------------------------- 38 | // Prototypes 39 | //----------------------------------------------------------------- 40 | 41 | // Initialise thread context 42 | void cpu_thread_init_tcb(struct cpu_tcb *tcb, void (*func)(void *), void *funcArg, uint32_t *stack, uint32_t stack_size ); 43 | 44 | // Start first thread switch 45 | void cpu_thread_start(void); 46 | 47 | // Force context switch 48 | void cpu_context_switch(void); 49 | 50 | // Force context switch (from IRQ) 51 | void cpu_context_switch_irq(void); 52 | 53 | // Critical section entry & exit 54 | int cpu_critical_start(void); 55 | void cpu_critical_end(int cr); 56 | 57 | // CPU specific idle function 58 | void cpu_idle(void); 59 | 60 | // Specified thread TCB's free stack entries count 61 | int cpu_thread_stack_free(struct cpu_tcb * pCurrent); 62 | 63 | // Specified thread TCB's total stack size 64 | int cpu_thread_stack_size(struct cpu_tcb * pCurrent); 65 | 66 | // CPU clocks/time measurement functions (optional, used if CONFIG_RTOS_MEASURE_THREAD_TIME defined) 67 | uint64_t cpu_timenow(void); 68 | int64_t cpu_timediff(uint64_t a, uint64_t b); 69 | 70 | // System specific assert handling function 71 | void cpu_thread_assert(const char *reason, const char *file, int line); 72 | 73 | #endif 74 | 75 | -------------------------------------------------------------------------------- /kernel/critical.h: -------------------------------------------------------------------------------- 1 | #ifndef __CRITICAL_H__ 2 | #define __CRITICAL_H__ 3 | 4 | #include "cpu_thread.h" 5 | 6 | //----------------------------------------------------------------- 7 | // critical_start: Force interrupts to be disabled (recursive ok) 8 | //----------------------------------------------------------------- 9 | static inline int critical_start(void) 10 | { 11 | return cpu_critical_start(); 12 | } 13 | //----------------------------------------------------------------- 14 | // critical_end: Restore interrupt enable state (recursive ok) 15 | //----------------------------------------------------------------- 16 | static inline void critical_end(int cr) 17 | { 18 | cpu_critical_end(cr); 19 | } 20 | 21 | #endif 22 | 23 | -------------------------------------------------------------------------------- /kernel/event.c: -------------------------------------------------------------------------------- 1 | #include "event.h" 2 | #include "critical.h" 3 | #include "os_assert.h" 4 | 5 | #ifdef INCLUDE_EVENTS 6 | 7 | //----------------------------------------------------------------- 8 | // event_init: Initialise event object 9 | //----------------------------------------------------------------- 10 | void event_init(struct event *ev) 11 | { 12 | OS_ASSERT(ev != NULL); 13 | 14 | ev->value = 0; 15 | semaphore_init(&ev->sema, 0); 16 | } 17 | //----------------------------------------------------------------- 18 | // event_get: Wait for an event to be set (returns bitmap) 19 | //----------------------------------------------------------------- 20 | uint32_t event_get(struct event *ev) 21 | { 22 | uint32_t value = 0; 23 | int cr; 24 | 25 | OS_ASSERT(ev != NULL); 26 | 27 | cr = critical_start(); 28 | 29 | // Wait for semaphore (it is safe to do this in a critical section) 30 | semaphore_pend(&ev->sema); 31 | 32 | // Retrieve event value & reset 33 | value = ev->value; 34 | ev->value = 0; 35 | 36 | critical_end(cr); 37 | 38 | return value; 39 | } 40 | //----------------------------------------------------------------- 41 | // event_set: Post event value (or add additional bits if already set) 42 | //----------------------------------------------------------------- 43 | void event_set(struct event *ev, uint32_t value) 44 | { 45 | int cr; 46 | 47 | OS_ASSERT(ev != NULL); 48 | OS_ASSERT(value); 49 | 50 | cr = critical_start(); 51 | 52 | // Already pending event 53 | if (ev->value != 0) 54 | { 55 | // Add additional bits to the bitmap 56 | ev->value |= value; 57 | } 58 | // No pending event 59 | else 60 | { 61 | ev->value = value; 62 | 63 | // Kick semaphore for first event 64 | semaphore_post(&ev->sema); 65 | } 66 | 67 | critical_end(cr); 68 | } 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /kernel/event.h: -------------------------------------------------------------------------------- 1 | #ifndef __EVENT_H__ 2 | #define __EVENT_H__ 3 | 4 | #include "thread.h" 5 | #include "semaphore.h" 6 | 7 | //----------------------------------------------------------------- 8 | // Defines 9 | //----------------------------------------------------------------- 10 | #define EVENT_INIT() {0, SEMAPHORE_INIT(0)} 11 | #define EVENT_DECL(id) \ 12 | static struct event event_ ## id = EVENT_INIT() 13 | 14 | //----------------------------------------------------------------- 15 | // Types 16 | //----------------------------------------------------------------- 17 | struct event 18 | { 19 | uint32_t value; 20 | struct semaphore sema; 21 | }; 22 | 23 | //----------------------------------------------------------------- 24 | // Prototypes 25 | //----------------------------------------------------------------- 26 | 27 | // Initialise event object 28 | void event_init(struct event *ev); 29 | 30 | // Wait for an event to be set (returns bitmap) 31 | void event_set(struct event *ev, uint32_t value); 32 | 33 | // Post event value (or add additional bits if already set) 34 | uint32_t event_get(struct event *ev); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /kernel/list.h: -------------------------------------------------------------------------------- 1 | #ifndef __LIST_H__ 2 | #define __LIST_H__ 3 | 4 | #ifndef LIST_ASSERT 5 | #define LIST_ASSERT(x) 6 | #endif 7 | 8 | //----------------------------------------------------------------- 9 | // Types 10 | //----------------------------------------------------------------- 11 | struct link_list; 12 | 13 | struct link_node 14 | { 15 | struct link_node *previous; 16 | struct link_node *next; 17 | }; 18 | 19 | struct link_list 20 | { 21 | struct link_node *head; 22 | struct link_node *tail; 23 | }; 24 | 25 | //----------------------------------------------------------------- 26 | // Macros 27 | //----------------------------------------------------------------- 28 | #define list_entry(p, t, m) p ? ((t *)((char *)(p)-(char*)(&((t *)0)->m))) : 0 29 | #define list_next(l, p) (p)->next 30 | #define list_prev(l, p) (p)->previous 31 | #define list_first(l) (l)->head 32 | #define list_last(l) (l)->tail 33 | #define list_for_each(l, p) for ((p) = (l)->head; (p); (p) = (p)->next) 34 | 35 | #define LIST_INIT {0, 0} 36 | 37 | //----------------------------------------------------------------- 38 | // Inline Functions 39 | //----------------------------------------------------------------- 40 | 41 | //----------------------------------------------------------------- 42 | // list_init: Initialise linked list 43 | //----------------------------------------------------------------- 44 | static inline void list_init(struct link_list *list) 45 | { 46 | LIST_ASSERT(list); 47 | 48 | list->head = list->tail = 0; 49 | } 50 | //----------------------------------------------------------------- 51 | // list_remove: Remove node from list 52 | //----------------------------------------------------------------- 53 | static inline void list_remove(struct link_list *list, struct link_node *node) 54 | { 55 | LIST_ASSERT(list); 56 | LIST_ASSERT(node); 57 | 58 | if(!node->previous) 59 | list->head = node->next; 60 | else 61 | node->previous->next = node->next; 62 | 63 | if(!node->next) 64 | list->tail = node->previous; 65 | else 66 | node->next->previous = node->previous; 67 | } 68 | //----------------------------------------------------------------- 69 | // list_insert_after: Insert 'new_node' after 'node' 70 | //----------------------------------------------------------------- 71 | static inline void list_insert_after(struct link_list *list, struct link_node *node, struct link_node *new_node) 72 | { 73 | LIST_ASSERT(list); 74 | LIST_ASSERT(node); 75 | LIST_ASSERT(new_node); 76 | 77 | new_node->previous = node; 78 | new_node->next = node->next; 79 | if (!node->next) 80 | list->tail = new_node; 81 | else 82 | node->next->previous = new_node; 83 | node->next = new_node; 84 | } 85 | //----------------------------------------------------------------- 86 | // list_insert_before: Insert 'new_node' before 'node' 87 | //----------------------------------------------------------------- 88 | static inline void list_insert_before(struct link_list *list, struct link_node *node, struct link_node *new_node) 89 | { 90 | LIST_ASSERT(list); 91 | LIST_ASSERT(node); 92 | LIST_ASSERT(new_node); 93 | 94 | new_node->previous = node->previous; 95 | new_node->next = node; 96 | if (!node->previous) 97 | list->head = new_node; 98 | else 99 | node->previous->next = new_node; 100 | node->previous = new_node; 101 | } 102 | //----------------------------------------------------------------- 103 | // list_insert_first: Insert 'node' as first item in the list 104 | //----------------------------------------------------------------- 105 | static inline void list_insert_first(struct link_list *list, struct link_node *node) 106 | { 107 | LIST_ASSERT(list); 108 | LIST_ASSERT(node); 109 | 110 | if (!list->head) 111 | { 112 | list->head = node; 113 | list->tail = node; 114 | node->previous = 0; 115 | node->next = 0; 116 | } 117 | else 118 | list_insert_before(list, list->head, node); 119 | } 120 | //----------------------------------------------------------------- 121 | // list_insert_last: Insert 'node' at the end of the list 122 | //----------------------------------------------------------------- 123 | static inline void list_insert_last(struct link_list *list, struct link_node *node) 124 | { 125 | LIST_ASSERT(list); 126 | LIST_ASSERT(node); 127 | 128 | if (!list->tail) 129 | list_insert_first(list, node); 130 | else 131 | list_insert_after(list, list->tail, node); 132 | } 133 | //----------------------------------------------------------------- 134 | // list_is_empty: Returns true if the list is empty 135 | //----------------------------------------------------------------- 136 | static inline int list_is_empty(struct link_list *list) 137 | { 138 | LIST_ASSERT(list); 139 | 140 | return !list->head; 141 | } 142 | 143 | #endif 144 | 145 | -------------------------------------------------------------------------------- /kernel/mailbox.c: -------------------------------------------------------------------------------- 1 | #include "mailbox.h" 2 | #include "critical.h" 3 | #include "os_assert.h" 4 | 5 | #ifdef INCLUDE_MAILBOX 6 | //----------------------------------------------------------------- 7 | // mailbox_init: Initialise mailbox 8 | //----------------------------------------------------------------- 9 | void mailbox_init(struct mailbox *pMbox, uint32_t *storage, int size) 10 | { 11 | int i; 12 | 13 | OS_ASSERT(pMbox != NULL); 14 | 15 | pMbox->entries = storage; 16 | 17 | for (i=0;ientries[i] = NULL; 19 | 20 | pMbox->head = 0; 21 | pMbox->tail = 0; 22 | pMbox->count = 0; 23 | pMbox->size = size; 24 | 25 | // Initialise mailbox item ready semaphore 26 | semaphore_init(&pMbox->sema, 0); 27 | } 28 | //----------------------------------------------------------------- 29 | // mailbox_post: Post message to mailbox 30 | //----------------------------------------------------------------- 31 | int mailbox_post(struct mailbox *pMbox, uint32_t val) 32 | { 33 | int cr; 34 | int res = 0; 35 | 36 | OS_ASSERT(pMbox != NULL); 37 | 38 | cr = critical_start(); 39 | 40 | // Mailbox has free space? 41 | if (pMbox->count < pMbox->size) 42 | { 43 | // Add pointer to mailbox 44 | pMbox->entries[pMbox->tail] = val; 45 | 46 | // Wrap? 47 | if (++pMbox->tail == pMbox->size) 48 | pMbox->tail = 0; 49 | 50 | // Increment mail count 51 | pMbox->count++; 52 | 53 | // Notify waiting threads that item added 54 | semaphore_post(&pMbox->sema); 55 | 56 | res = 1; 57 | } 58 | // Mailbox full! 59 | else 60 | res = 0; 61 | 62 | critical_end(cr); 63 | 64 | return res; 65 | } 66 | //----------------------------------------------------------------- 67 | // mailbox_pend: Wait for mailbox message 68 | //----------------------------------------------------------------- 69 | void mailbox_pend(struct mailbox *pMbox, uint32_t *val) 70 | { 71 | int cr; 72 | 73 | OS_ASSERT(pMbox != NULL); 74 | 75 | cr = critical_start(); 76 | 77 | // Pend on a new item being added 78 | semaphore_pend(&pMbox->sema); 79 | 80 | OS_ASSERT(pMbox->count > 0); 81 | 82 | // Retrieve the mail 83 | if (val) 84 | *val = pMbox->entries[pMbox->head]; 85 | 86 | // Wrap 87 | if (++pMbox->head == pMbox->size) 88 | pMbox->head = 0; 89 | 90 | // Decrement items in queue 91 | pMbox->count--; 92 | 93 | critical_end(cr); 94 | } 95 | //----------------------------------------------------------------- 96 | // mailbox_pend_timed: Wait for mailbox message (with timeout) 97 | // Returns: 1 = mail retrieved, 0 = timeout 98 | //----------------------------------------------------------------- 99 | int mailbox_pend_timed(struct mailbox *pMbox, uint32_t *val, int timeoutMs) 100 | { 101 | int cr; 102 | int result = 0; 103 | 104 | OS_ASSERT(pMbox != NULL); 105 | 106 | cr = critical_start(); 107 | 108 | // Wait for specified timeout period 109 | if (semaphore_timed_pend(&pMbox->sema, timeoutMs)) 110 | { 111 | OS_ASSERT(pMbox->count > 0); 112 | 113 | // Retrieve the mail 114 | if (val) 115 | *val = pMbox->entries[pMbox->head]; 116 | 117 | // Wrap 118 | if (++pMbox->head == pMbox->size) 119 | pMbox->head = 0; 120 | 121 | // Decrement items in queue 122 | pMbox->count--; 123 | 124 | result = 1; 125 | } 126 | 127 | critical_end(cr); 128 | 129 | return result; 130 | } 131 | #endif 132 | -------------------------------------------------------------------------------- /kernel/mailbox.h: -------------------------------------------------------------------------------- 1 | #ifndef __MAILBOX_H__ 2 | #define __MAILBOX_H__ 3 | 4 | #include "thread.h" 5 | #include "list.h" 6 | #include "semaphore.h" 7 | 8 | //----------------------------------------------------------------- 9 | // Defines 10 | //----------------------------------------------------------------- 11 | #define MAILBOX_INIT(e, s) {(e), (s), 0, 0, 0, SEMAPHORE_INIT(0)} 12 | #define MAILBOX_DECL(id, size) \ 13 | static uint32_t stack_ ## id[size]; \ 14 | static struct mailbox mbox_ ## id = MAILBOX_INIT(stack_ ## id, size) 15 | 16 | //----------------------------------------------------------------- 17 | // Types 18 | //----------------------------------------------------------------- 19 | struct mailbox 20 | { 21 | // Storage array 22 | uint32_t *entries; 23 | 24 | // Total size of storage 25 | int size; 26 | 27 | // Access Pointers 28 | int head; 29 | int tail; 30 | 31 | // Number of entries currently present 32 | int count; 33 | 34 | struct semaphore sema; 35 | }; 36 | 37 | //----------------------------------------------------------------- 38 | // Prototypes 39 | //----------------------------------------------------------------- 40 | 41 | // Initialise mailbox 42 | void mailbox_init(struct mailbox *pMbox, uint32_t *storage, int size); 43 | 44 | // Post message to mailbox 45 | int mailbox_post(struct mailbox *pMbox, uint32_t val); 46 | 47 | // Wait for mailbox message 48 | void mailbox_pend(struct mailbox *pMbox, uint32_t *val); 49 | 50 | // Wait for mailbox message (with timeout) 51 | int mailbox_pend_timed(struct mailbox *pMbox, uint32_t *val, int timeoutMs); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /kernel/mutex.c: -------------------------------------------------------------------------------- 1 | #include "mutex.h" 2 | #include "thread.h" 3 | #include "critical.h" 4 | #include "os_assert.h" 5 | 6 | #ifdef INCLUDE_MUTEX 7 | //----------------------------------------------------------------- 8 | // mutex_init: Initialise mutex 9 | //----------------------------------------------------------------- 10 | void mutex_init(struct mutex *mtx, int recursive) 11 | { 12 | OS_ASSERT(mtx != NULL); 13 | 14 | // No default owner 15 | mtx->owner = NULL; 16 | 17 | // No recursive depth count yet 18 | mtx->depth = 0; 19 | 20 | // Is this mutex recursive 21 | mtx->recursive = recursive; 22 | 23 | // Pending thread list 24 | list_init(&mtx->pend_list); 25 | } 26 | //----------------------------------------------------------------- 27 | // mutex_lock: Acquire mutex (optionally recursive) 28 | //----------------------------------------------------------------- 29 | void mutex_lock(struct mutex *mtx) 30 | { 31 | struct thread* this_thread; 32 | int cr; 33 | 34 | OS_ASSERT(mtx != NULL); 35 | 36 | cr = critical_start(); 37 | 38 | // Get current (this) thread 39 | this_thread = thread_current(); 40 | 41 | // Is the mutex not already locked 42 | if (mtx->owner == NULL) 43 | { 44 | // Acquire mutex for this thread 45 | mtx->owner = this_thread; 46 | 47 | OS_ASSERT(mtx->depth == 0); 48 | } 49 | // Is the mutex already locked by this thread 50 | else if (mtx->recursive && mtx->owner == this_thread) 51 | { 52 | // Increase recursive depth 53 | mtx->depth++; 54 | } 55 | // The mutex is already 'owned', add thread to pending list 56 | else 57 | { 58 | struct link_node *listnode; 59 | 60 | OS_ASSERT(mtx->owner != this_thread); 61 | 62 | // Get list node 63 | listnode = &this_thread->blocking_node; 64 | 65 | // Add node to end of pending list 66 | list_insert_last(&mtx->pend_list, listnode); 67 | 68 | // Block the thread from running 69 | thread_block(this_thread); 70 | } 71 | 72 | critical_end(cr); 73 | } 74 | //----------------------------------------------------------------- 75 | // mutex_trylock: Acquire mutex, return 1 if acquired, 0 if not 76 | //----------------------------------------------------------------- 77 | int mutex_trylock(struct mutex *mtx) 78 | { 79 | struct thread* this_thread; 80 | int cr; 81 | int result = 0; 82 | 83 | OS_ASSERT(mtx != NULL); 84 | 85 | cr = critical_start(); 86 | 87 | // Get current (this) thread 88 | this_thread = thread_current(); 89 | 90 | // Is the mutex not already locked 91 | if (mtx->owner == NULL) 92 | { 93 | // Acquire mutex for this thread 94 | mtx->owner = this_thread; 95 | 96 | OS_ASSERT(mtx->depth == 0); 97 | result = 1; 98 | } 99 | // Is the mutex already locked by this thread 100 | else if (mtx->recursive && mtx->owner == this_thread) 101 | { 102 | // Increase recursive depth 103 | mtx->depth++; 104 | result = 1; 105 | } 106 | // The mutex is already 'owned' by another thread, fail 107 | else 108 | result = 0; 109 | 110 | critical_end(cr); 111 | 112 | return result; 113 | } 114 | //----------------------------------------------------------------- 115 | // mutex_unlock: Release mutex (optionally recursive) 116 | //----------------------------------------------------------------- 117 | void mutex_unlock(struct mutex *mtx) 118 | { 119 | struct thread* this_thread; 120 | int cr; 121 | 122 | OS_ASSERT(mtx != NULL); 123 | 124 | cr = critical_start(); 125 | 126 | // Get current (this) thread 127 | this_thread = thread_current(); 128 | 129 | // We cannot release a mutex that we dont own! 130 | OS_ASSERT(this_thread == mtx->owner); 131 | 132 | // Reduce recursive depth count 133 | if (mtx->depth > 0) 134 | mtx->depth--; 135 | // If there are threads pending on this mutex 136 | else if (!list_is_empty(&mtx->pend_list)) 137 | { 138 | // Unblock the first pending thread 139 | struct link_node *node = list_first(&mtx->pend_list); 140 | 141 | // Get the thread item 142 | struct thread* thread = list_entry(node, struct thread, blocking_node); 143 | 144 | // Remove node from linked list 145 | list_remove(&mtx->pend_list, node); 146 | 147 | // Transfer mutex ownership 148 | mtx->owner = thread; 149 | 150 | // Unblock the first waiting thread 151 | thread_unblock(thread); 152 | } 153 | // Else no-one wants it, no owner 154 | else 155 | mtx->owner = NULL; 156 | 157 | critical_end(cr); 158 | } 159 | #endif 160 | -------------------------------------------------------------------------------- /kernel/mutex.h: -------------------------------------------------------------------------------- 1 | #ifndef __MUTEX_H__ 2 | #define __MUTEX_H__ 3 | 4 | #include "list.h" 5 | 6 | //----------------------------------------------------------------- 7 | // Defines 8 | //----------------------------------------------------------------- 9 | #define MUTEX_INIT() {0, 0, 0, LIST_INIT} 10 | #define MUTEX_INIT_RECURSIVE() {0, 1, 0, LIST_INIT} 11 | #define MUTEX_DECL(id) \ 12 | static struct mutex mtx_ ## id = MUTEX_INIT() 13 | 14 | //----------------------------------------------------------------- 15 | // Types 16 | //----------------------------------------------------------------- 17 | struct mutex 18 | { 19 | void * owner; 20 | int recursive; 21 | int depth; 22 | struct link_list pend_list; 23 | }; 24 | 25 | //----------------------------------------------------------------- 26 | // Prototypes 27 | //----------------------------------------------------------------- 28 | 29 | // Initialise mutex 30 | void mutex_init(struct mutex *mtx, int recursive); 31 | 32 | // Acquire mutex (optionally recursive) 33 | void mutex_lock(struct mutex *mtx); 34 | 35 | // Acquire mutex, return 1 if acquired, 0 if not 36 | int mutex_trylock(struct mutex *mtx); 37 | 38 | // Release mutex (optionally recursive) 39 | void mutex_unlock(struct mutex *mtx); 40 | 41 | #endif 42 | 43 | -------------------------------------------------------------------------------- /kernel/os_assert.h: -------------------------------------------------------------------------------- 1 | #ifndef __OS_ASSERT_H__ 2 | #define __OS_ASSERT_H__ 3 | 4 | #include "cpu_thread.h" 5 | 6 | // To disable RTOS assertions then define CONFIG_RTOS_RELEASE_MODE 7 | 8 | //----------------------------------------------------------------- 9 | // DEBUG 10 | //----------------------------------------------------------------- 11 | #ifndef CONFIG_RTOS_RELEASE_MODE 12 | 13 | #define OS_ASSERT(exp) do { if (!(exp)) cpu_thread_assert(#exp, __FILE__, __LINE__); } while (0) 14 | #define OS_PANIC(reason) cpu_thread_assert(reason, __FILE__, __LINE__) 15 | 16 | //----------------------------------------------------------------- 17 | // RELEASE 18 | //----------------------------------------------------------------- 19 | #else 20 | 21 | #define OS_ASSERT(exp) ((void)0) 22 | #define OS_PANIC(reason) while (1) 23 | 24 | #endif 25 | 26 | #endif 27 | 28 | -------------------------------------------------------------------------------- /kernel/semaphore.c: -------------------------------------------------------------------------------- 1 | #include "semaphore.h" 2 | #include "critical.h" 3 | #include "os_assert.h" 4 | 5 | #ifdef INCLUDE_SEMAPHORE 6 | //----------------------------------------------------------------- 7 | // semaphore_init: Initialise semaphore with an initial value 8 | //----------------------------------------------------------------- 9 | void semaphore_init(struct semaphore *pSem, uint32_t initial_count) 10 | { 11 | OS_ASSERT(pSem != NULL); 12 | 13 | // Initial semaphore count value 14 | pSem->count = initial_count; 15 | 16 | // Pending thread list 17 | list_init(&pSem->pend_list); 18 | } 19 | //----------------------------------------------------------------- 20 | // semaphore_pend: Decrement semaphore or block if already 0 21 | //----------------------------------------------------------------- 22 | void semaphore_pend(struct semaphore *pSem) 23 | { 24 | int cr; 25 | 26 | OS_ASSERT(pSem != NULL); 27 | 28 | cr = critical_start(); 29 | 30 | // If one immediatly available 31 | if (pSem->count > 0) 32 | pSem->count--; 33 | // None available, add to queue 34 | else 35 | { 36 | struct link_node *listnode; 37 | 38 | // Get current (this) thread 39 | struct thread* this_thread = thread_current(); 40 | 41 | // Setup list node 42 | listnode = &this_thread->blocking_node; 43 | 44 | // Add node to end of pending list 45 | list_insert_last(&pSem->pend_list, listnode); 46 | 47 | // Block the thread from running 48 | thread_block(this_thread); 49 | } 50 | 51 | critical_end(cr); 52 | } 53 | //----------------------------------------------------------------- 54 | // semaphore_post: Increment semaphore count 55 | //----------------------------------------------------------------- 56 | static void semaphore_post_internal(struct semaphore *pSem, int irq) 57 | { 58 | int cr; 59 | 60 | OS_ASSERT(pSem != NULL); 61 | 62 | cr = critical_start(); 63 | 64 | // Increment semaphore count 65 | pSem->count++; 66 | 67 | // If there are threads pending on this semaphore 68 | if (!list_is_empty(&pSem->pend_list)) 69 | { 70 | // Unblock the first pending thread 71 | struct link_node *node = list_first(&pSem->pend_list); 72 | 73 | // Get the thread item 74 | struct thread* thread = list_entry(node, struct thread, blocking_node); 75 | 76 | // Remove node from linked list 77 | list_remove(&pSem->pend_list, node); 78 | 79 | // Count down semaphore which has been taken by the 80 | // pending thread... 81 | pSem->count--; 82 | 83 | // Tell anyone who cares what caused the thread to be unblocked... 84 | thread->unblocking_arg = node; 85 | 86 | // Unblock the waiting thread 87 | if (irq) 88 | thread_unblock_irq(thread); 89 | else 90 | thread_unblock(thread); 91 | } 92 | 93 | critical_end(cr); 94 | } 95 | //----------------------------------------------------------------- 96 | // semaphore_post: Increment semaphore count 97 | //----------------------------------------------------------------- 98 | void semaphore_post(struct semaphore *pSem) 99 | { 100 | semaphore_post_internal(pSem, 0); 101 | } 102 | //----------------------------------------------------------------- 103 | // semaphore_post_irq: Increment semaphore (interrupt context safe) 104 | //----------------------------------------------------------------- 105 | void semaphore_post_irq(struct semaphore *pSem) 106 | { 107 | semaphore_post_internal(pSem, 1); 108 | } 109 | //----------------------------------------------------------------- 110 | // semaphore_try: Attempt to decrement semaphore or return 0 111 | //----------------------------------------------------------------- 112 | int semaphore_try(struct semaphore *pSem) 113 | { 114 | int result; 115 | int cr; 116 | 117 | OS_ASSERT(pSem != NULL); 118 | 119 | cr = critical_start(); 120 | 121 | // If one immediatly available 122 | if (pSem->count > 0) 123 | { 124 | pSem->count--; 125 | result = 1; 126 | } 127 | // None available currently 128 | else 129 | result = 0; 130 | 131 | critical_end(cr); 132 | 133 | return result; 134 | } 135 | //----------------------------------------------------------------- 136 | // semaphore_timed_pend: Decrement semaphore (with timeout) 137 | //----------------------------------------------------------------- 138 | int semaphore_timed_pend(struct semaphore *pSem, int timeoutMs) 139 | { 140 | int cr; 141 | int result = 0; 142 | 143 | OS_ASSERT(pSem != NULL); 144 | 145 | cr = critical_start(); 146 | 147 | // If one immediatly available 148 | if (pSem->count > 0) 149 | { 150 | pSem->count--; 151 | result = 1; 152 | } 153 | // None available, add to queue (if timeout specified) 154 | else if (timeoutMs > 0) 155 | { 156 | struct link_node *listnode; 157 | 158 | // Get current (this) thread 159 | struct thread* this_thread = thread_current(); 160 | 161 | // Setup list node 162 | listnode = &this_thread->blocking_node; 163 | 164 | // Add node to end of pending list 165 | list_insert_last(&pSem->pend_list, listnode); 166 | 167 | // Clear unblocking arg 168 | this_thread->unblocking_arg = NULL; 169 | 170 | // Send the thread to sleep for the timeout period 171 | thread_sleep(timeoutMs); 172 | 173 | // Is the thread awake due to a semaphore_post? 174 | if (this_thread->unblocking_arg != NULL) 175 | result = 1; 176 | // Else we must have timed out 177 | else 178 | { 179 | struct link_list *pList = &pSem->pend_list; 180 | struct link_node *node; 181 | 182 | // Walk the list 183 | list_for_each(pList, node) 184 | { 185 | struct thread *node_thread = list_entry(node, struct thread, blocking_node); 186 | 187 | // Is this us? 188 | if (this_thread == node_thread) 189 | { 190 | // Remove node from linked list 191 | list_remove(pList, node); 192 | 193 | // Stop scanning this list! 194 | break; 195 | } 196 | } 197 | 198 | // We should not have reached the end of the list without finding our entry. 199 | OS_ASSERT(node != NULL); 200 | 201 | result = 0; 202 | } 203 | } 204 | 205 | critical_end(cr); 206 | 207 | return result; 208 | } 209 | //----------------------------------------------------------------- 210 | // semaphore_get_value: Value access 211 | //----------------------------------------------------------------- 212 | uint32_t semaphore_get_value(struct semaphore *pSem) 213 | { 214 | OS_ASSERT(pSem != NULL); 215 | 216 | return pSem->count; 217 | } 218 | #endif 219 | -------------------------------------------------------------------------------- /kernel/semaphore.h: -------------------------------------------------------------------------------- 1 | #ifndef __SEMAPHORE_H__ 2 | #define __SEMAPHORE_H__ 3 | 4 | #include "thread.h" 5 | #include "list.h" 6 | 7 | //----------------------------------------------------------------- 8 | // Defines 9 | //----------------------------------------------------------------- 10 | #define SEMAPHORE_INIT(c) {(c), LIST_INIT} 11 | #define SEMAPHORE_DECL(id, c) \ 12 | static struct semaphore sema_ ## id = SEMAPHORE_INIT(c) 13 | 14 | //----------------------------------------------------------------- 15 | // Types 16 | //----------------------------------------------------------------- 17 | struct semaphore 18 | { 19 | uint32_t count; 20 | struct link_list pend_list; 21 | }; 22 | 23 | //----------------------------------------------------------------- 24 | // Prototypes 25 | //----------------------------------------------------------------- 26 | 27 | // Initialise semaphore with an initial value 28 | void semaphore_init(struct semaphore *pSem, uint32_t initial_count); 29 | 30 | // Increment semaphore count 31 | void semaphore_post(struct semaphore *pSem); 32 | 33 | // Increment semaphore (interrupt context safe) 34 | void semaphore_post_irq(struct semaphore *pSem); 35 | 36 | // Decrement semaphore or block if already 0 37 | void semaphore_pend(struct semaphore *pSem); 38 | 39 | // Attempt to decrement semaphore or return 0 40 | int semaphore_try(struct semaphore *pSem); 41 | 42 | // Decrement semaphore (with timeout) 43 | int semaphore_timed_pend(struct semaphore *pSem, int timeoutMs); 44 | 45 | // Get semaphore value 46 | uint32_t semaphore_get_value(struct semaphore *pSem); 47 | 48 | #endif 49 | 50 | -------------------------------------------------------------------------------- /kernel/thread.c: -------------------------------------------------------------------------------- 1 | #include "thread.h" 2 | #include "critical.h" 3 | #include "os_assert.h" 4 | 5 | //----------------------------------------------------------------- 6 | // Defines: 7 | //----------------------------------------------------------------- 8 | #ifdef PLATFORM_IDLE_TASK_STACK 9 | #define IDLE_TASK_STACK PLATFORM_IDLE_TASK_STACK 10 | #else 11 | #define IDLE_TASK_STACK 256 12 | #endif 13 | 14 | //----------------------------------------------------------------- 15 | // Locals: 16 | //----------------------------------------------------------------- 17 | static struct link_list _thread_runnable; 18 | static struct link_list _thread_blocked; 19 | static struct link_list _thread_sleeping; 20 | static struct link_list _thread_dead; 21 | static struct thread* _current_thread = NULL; 22 | static struct thread _idle_task; 23 | static struct thread* _thread_list_all = NULL; 24 | static volatile uint32_t _tick_count; 25 | static volatile uint32_t _thread_picks; 26 | static uint32_t _idle_task_stack[IDLE_TASK_STACK]; 27 | static int _thread_id; 28 | static int _initd = 0; 29 | static int _running; 30 | 31 | //----------------------------------------------------------------- 32 | // Prototypes: 33 | //----------------------------------------------------------------- 34 | static void * thread_idle_task(void* arg); 35 | static struct thread* thread_pick(void); 36 | static void thread_func(void *pThd); 37 | 38 | static void thread_switch(void); 39 | static void thread_insert_priority(struct link_list *pList, struct thread *pInsertNode); 40 | static void thread_unblock_int(struct thread *pThread); 41 | 42 | //----------------------------------------------------------------- 43 | // thread_kernel_init: Initialise the RTOS kernel 44 | //----------------------------------------------------------------- 45 | int thread_kernel_init(void) 46 | { 47 | OS_ASSERT(!_initd); 48 | 49 | // Disable interrupts 50 | critical_start(); 51 | 52 | // Initialise thread lists 53 | list_init(&_thread_runnable); 54 | list_init(&_thread_sleeping); 55 | list_init(&_thread_blocked); 56 | list_init(&_thread_dead); 57 | 58 | _thread_list_all = NULL; 59 | _thread_id = 0; 60 | _tick_count = 0; 61 | _thread_picks = 0; 62 | _running = 0; 63 | 64 | // Create an idle task 65 | thread_init(&_idle_task, "IDLE_TASK", THREAD_IDLE_PRIO, thread_idle_task, (void*)NULL, (void*)_idle_task_stack, IDLE_TASK_STACK); 66 | 67 | _initd = 1; 68 | return 1; 69 | } 70 | //----------------------------------------------------------------- 71 | // thread_kernel_run: Start the RTOS kernel 72 | //----------------------------------------------------------------- 73 | void thread_kernel_run(void) 74 | { 75 | OS_ASSERT(_initd); 76 | OS_ASSERT(!_running); 77 | 78 | // Start with idle task so we then pick the best thread to 79 | // run rather than the first in the list 80 | _current_thread = &_idle_task; 81 | _running = TRUE; 82 | 83 | // Switch context to the highest priority thread 84 | cpu_thread_start(); 85 | } 86 | //----------------------------------------------------------------- 87 | // thread_init_ex: Init thread with specified start state 88 | //----------------------------------------------------------------- 89 | int thread_init_ex(struct thread *pThread, const char *name, int pri, void *(*f)(void *), void *arg, void *stack, uint32_t stack_size, tThreadState initial_state) 90 | { 91 | int cr; 92 | int l = 0; 93 | 94 | OS_ASSERT(pThread != NULL); 95 | 96 | // Thread name 97 | if (!name) 98 | name = "NO_NAME"; 99 | 100 | while (l < THREAD_NAME_LEN && name[l]) 101 | { 102 | pThread->name[l] = name[l]; 103 | l++; 104 | } 105 | 106 | pThread->name[THREAD_NAME_LEN-1] = 0; 107 | 108 | // Setup priority 109 | pThread->priority = pri; 110 | 111 | // Thread function 112 | pThread->thread_func = f; 113 | pThread->thread_arg = arg; 114 | 115 | pThread->state = initial_state; 116 | pThread->run_count = 0; 117 | pThread->exit_value = NULL; 118 | 119 | #ifdef CONFIG_RTOS_ABSOLUTE_TIME 120 | pThread->wakeup_time = 0; 121 | #else 122 | pThread->wait_delta = 0; 123 | #endif 124 | 125 | #ifdef CONFIG_RTOS_MEASURE_THREAD_TIME 126 | pThread->run_time = 0; 127 | pThread->run_start = 0; 128 | #endif 129 | 130 | // Join list init 131 | list_init(&pThread->join_list); 132 | 133 | // Task control block 134 | cpu_thread_init_tcb(&pThread->tcb, thread_func, pThread, stack, stack_size); 135 | 136 | // Begin critical section 137 | cr = critical_start(); 138 | 139 | pThread->thread_id = ++_thread_id; 140 | 141 | // Runable: Insert this thread at the end of run list 142 | if (initial_state == THREAD_RUNABLE) 143 | thread_insert_priority(&_thread_runnable, pThread); 144 | else if (initial_state == THREAD_BLOCKED) 145 | list_insert_last(&_thread_blocked, &pThread->node); 146 | else 147 | { 148 | OS_ASSERT(initial_state != THREAD_SLEEPING); 149 | } 150 | 151 | // Add to simple all threads list 152 | pThread->next_all = _thread_list_all; 153 | _thread_list_all = pThread; 154 | 155 | // Set the checkword 156 | pThread->checkword = THREAD_CHECK_WORD; 157 | 158 | critical_end(cr); 159 | 160 | return 1; 161 | } 162 | //----------------------------------------------------------------- 163 | // thread_init: Init thread (runnable now) 164 | //----------------------------------------------------------------- 165 | int thread_init(struct thread *pThread, const char *name, int pri, void *(*f)(void *), void *arg, void *stack, uint32_t stack_size) 166 | { 167 | return thread_init_ex(pThread, name, pri, f, arg, stack, stack_size, THREAD_RUNABLE); 168 | } 169 | //----------------------------------------------------------------- 170 | // thread_kill: Kill thread and remove from all thread lists. 171 | // Once complete, thread data/stack will not be accessed again by 172 | // RTOS. 173 | // You cannot kill a thread from itself, use thread_suicide instead. 174 | // Returns: 1 = ok, 0 = failed 175 | //----------------------------------------------------------------- 176 | int thread_kill(struct thread *pThread) 177 | { 178 | int ok = 0; 179 | struct thread *pCurr = NULL; 180 | struct thread *pLast = NULL; 181 | int cr = critical_start(); 182 | 183 | // Thread cannot kill itself using thread_kill 184 | if (pThread != _current_thread) 185 | { 186 | // Thread currently runable: remove from run list 187 | if (pThread->state == THREAD_RUNABLE) 188 | list_remove(&_thread_runnable, &pThread->node); 189 | // Blocked: remove from blocked list 190 | else if (pThread->state == THREAD_BLOCKED) 191 | list_remove(&_thread_blocked, &pThread->node); 192 | // Sleeping: remove from sleep list 193 | else if (pThread->state == THREAD_SLEEPING) 194 | { 195 | #ifndef CONFIG_RTOS_ABSOLUTE_TIME 196 | // Is there another thread after this in the delta timer list? 197 | struct link_node *node = list_next(&_thread_sleeping, &pThread->node); 198 | if (node) 199 | { 200 | struct thread *pNextThread = list_entry(node, struct thread, node); 201 | 202 | // Add current item's remaining time to next 203 | pNextThread->wait_delta += pThread->wait_delta; 204 | } 205 | #endif 206 | // Remove from sleeping list 207 | list_remove(&_thread_sleeping, &pThread->node); 208 | } 209 | // Dead: Remove from dead list 210 | else if (pThread->state == THREAD_DEAD) 211 | list_remove(&_thread_dead, &pThread->node); 212 | else 213 | OS_PANIC("Unknown thread state!"); 214 | 215 | // Remove from simple 'all threads' list 216 | pCurr = _thread_list_all; 217 | while (pCurr != NULL) 218 | { 219 | if (pCurr == pThread) 220 | { 221 | if (pLast != NULL) 222 | pLast->next_all = pCurr->next_all; 223 | else 224 | _thread_list_all = pCurr->next_all; 225 | break; 226 | } 227 | else 228 | pCurr = pCurr->next_all; 229 | 230 | pLast = pCurr; 231 | } 232 | 233 | ok = 1; 234 | } 235 | 236 | critical_end(cr); 237 | 238 | return ok; 239 | } 240 | //----------------------------------------------------------------- 241 | // thread_suicide: Allows a thread to self terminate. 242 | //----------------------------------------------------------------- 243 | void thread_suicide(struct thread *pThread, void *exit_arg) 244 | { 245 | int cr = critical_start(); 246 | 247 | OS_ASSERT(pThread == _current_thread); 248 | OS_ASSERT(pThread->state == THREAD_RUNABLE); 249 | 250 | // Remove from the run list 251 | list_remove(&_thread_runnable, &pThread->node); 252 | 253 | // Mark thread as dead and add to dead thread list 254 | pThread->state = THREAD_DEAD; 255 | list_insert_last(&_thread_dead, &pThread->node); 256 | 257 | // Record optional exit arg for later use 258 | pThread->exit_value = exit_arg; 259 | 260 | // If there are threads pending on this thread exiting 261 | while (!list_is_empty(&pThread->join_list)) 262 | { 263 | // Unblock the first pending thread 264 | struct link_node *node = list_first(&pThread->join_list); 265 | 266 | // Get the thread item 267 | struct thread* thread = list_entry(node, struct thread, blocking_node); 268 | 269 | // Remove node from linked list 270 | list_remove(&pThread->join_list, node); 271 | 272 | // Unblock the waiting thread 273 | thread_unblock_int(thread); 274 | } 275 | 276 | // Switch context to the new highest priority thread 277 | cpu_context_switch(); 278 | 279 | critical_end(cr); 280 | } 281 | //----------------------------------------------------------------- 282 | // thread_join: Wait for thread to exit 283 | //----------------------------------------------------------------- 284 | void* thread_join(struct thread *pThread) 285 | { 286 | void *res; 287 | int cr; 288 | 289 | OS_ASSERT(pThread); 290 | 291 | // Can't wait for ourselves to exit! 292 | OS_ASSERT(pThread != _current_thread); 293 | 294 | cr = critical_start(); 295 | 296 | // If thread alive 297 | if (pThread->state != THREAD_DEAD) 298 | { 299 | // Setup list node 300 | struct link_node * listnode = &_current_thread->blocking_node; 301 | 302 | // Add node to end of pending join list 303 | list_insert_last(&pThread->join_list, listnode); 304 | 305 | // Block the thread from running 306 | thread_block(_current_thread); 307 | } 308 | 309 | res = pThread->exit_value; 310 | 311 | critical_end(cr); 312 | 313 | return res; 314 | } 315 | //----------------------------------------------------------------- 316 | // thread_sleep_thread: Put a specific thread on to the sleep queue 317 | //----------------------------------------------------------------- 318 | void thread_sleep_thread(struct thread *pSleepThread, uint32_t time_units) 319 | { 320 | int cr = critical_start(); 321 | #ifndef CONFIG_RTOS_ABSOLUTE_TIME 322 | uint32_t total = 0; 323 | uint32_t prevtotal = 0; 324 | #endif 325 | struct link_node *node; 326 | 327 | OS_ASSERT(pSleepThread); 328 | 329 | // Is the thread currently runable? 330 | if (pSleepThread->state == THREAD_RUNABLE) 331 | { 332 | // Remove from the run list 333 | list_remove(&_thread_runnable, &pSleepThread->node); 334 | } 335 | // or is it blocked 336 | else if (pSleepThread->state == THREAD_BLOCKED) 337 | { 338 | // Remove from the blocked list 339 | list_remove(&_thread_blocked, &pSleepThread->node); 340 | } 341 | else 342 | OS_PANIC("Thread already sleeping!"); 343 | 344 | // Mark thread as sleeping 345 | pSleepThread->state = THREAD_SLEEPING; 346 | 347 | #ifdef CONFIG_RTOS_ABSOLUTE_TIME 348 | pSleepThread->wakeup_time = cpu_timenow(); 349 | pSleepThread->wakeup_time+= time_units; 350 | #else 351 | // NOTE: Add 1 to the sleep time to get at least the time slept for. 352 | time_units = time_units + 1; 353 | #endif 354 | 355 | // Get the first sleeping thread 356 | node = list_first(&_thread_sleeping); 357 | 358 | // Current sleep list is empty? 359 | if (node == NULL) 360 | { 361 | #ifndef CONFIG_RTOS_ABSOLUTE_TIME 362 | // delta is total timeout 363 | pSleepThread->wait_delta = time_units; 364 | #endif 365 | // Add to the start of the sleep list 366 | list_insert_first(&_thread_sleeping, &pSleepThread->node); 367 | } 368 | // Timer list has items 369 | else 370 | { 371 | // Iterate through current list and add at correct location 372 | for ( ; node ; node = list_next(&_thread_sleeping, node)) 373 | { 374 | // Get the thread item 375 | struct thread * pThread = list_entry(node, struct thread, node); 376 | 377 | #ifndef CONFIG_RTOS_ABSOLUTE_TIME 378 | // Increment cumulative total 379 | total += pThread->wait_delta; 380 | #endif 381 | 382 | // New timeout less than total (or end of list reached) 383 | #ifdef CONFIG_RTOS_ABSOLUTE_TIME 384 | if (pSleepThread->wakeup_time <= pThread->wakeup_time) 385 | #else 386 | if (time_units <= total) 387 | #endif 388 | { 389 | #ifndef CONFIG_RTOS_ABSOLUTE_TIME 390 | // delta time from previous to this node 391 | pSleepThread->wait_delta = time_units - prevtotal; 392 | #endif 393 | 394 | // Insert into list before this sleeping thread 395 | list_insert_before(&_thread_sleeping, &pThread->node, &pSleepThread->node); 396 | 397 | #ifndef CONFIG_RTOS_ABSOLUTE_TIME 398 | // Adjust next nodes delta time 399 | pThread->wait_delta -= pSleepThread->wait_delta; 400 | #endif 401 | break; 402 | } 403 | 404 | #ifndef CONFIG_RTOS_ABSOLUTE_TIME 405 | prevtotal = total; 406 | #endif 407 | 408 | // End of list reached, still not added 409 | if (list_next(&_thread_sleeping, node) == NULL) 410 | { 411 | #ifndef CONFIG_RTOS_ABSOLUTE_TIME 412 | // delta time from previous to this node 413 | pSleepThread->wait_delta = time_units - prevtotal; 414 | #endif 415 | 416 | // Insert into list after last node (end of list) 417 | list_insert_last(&_thread_sleeping, &pSleepThread->node); 418 | break; 419 | } 420 | } 421 | } 422 | 423 | critical_end(cr); 424 | } 425 | //----------------------------------------------------------------- 426 | // thread_sleep_cancel: Stop a thread from sleeping 427 | //----------------------------------------------------------------- 428 | void thread_sleep_cancel(struct thread *pThread) 429 | { 430 | int cr = critical_start(); 431 | 432 | OS_ASSERT(pThread); 433 | 434 | // If the item has not already expired (and is in the sleeping list) 435 | if (pThread->state == THREAD_SLEEPING) 436 | { 437 | #ifndef CONFIG_RTOS_ABSOLUTE_TIME 438 | // Is there another thread after this in the delta list? 439 | struct link_node *node = list_next(&_thread_sleeping, &pThread->node); 440 | if (node) 441 | { 442 | struct thread *pNextThread = list_entry(node, struct thread, node); 443 | 444 | // Add current item's remaining time to next 445 | pNextThread->wait_delta += pThread->wait_delta; 446 | } 447 | 448 | // Clear the sleep timer 449 | pThread->wait_delta = 0; 450 | #endif 451 | 452 | // Remove from the sleeping list 453 | list_remove(&_thread_sleeping, &pThread->node); 454 | 455 | // Until this thread is put back in the run list or 456 | // is re-added to the sleep list then mark as blocked. 457 | pThread->state = THREAD_BLOCKED; 458 | list_insert_last(&_thread_blocked, &pThread->node); 459 | } 460 | // Else thread timeout has expired and is now runable (or blocked) 461 | 462 | critical_end(cr); 463 | } 464 | //----------------------------------------------------------------- 465 | // thread_sleep: Sleep thread for x time units 466 | //----------------------------------------------------------------- 467 | void thread_sleep(uint32_t time_units) 468 | { 469 | int cr = critical_start(); 470 | 471 | // Put the current thread to sleep 472 | if (time_units > 0) 473 | thread_sleep_thread(_current_thread, time_units); 474 | 475 | // Switch context to the next highest priority thread 476 | thread_switch(); 477 | 478 | critical_end(cr); 479 | } 480 | //----------------------------------------------------------------- 481 | // thread_switch: Switch context to the highest priority thread 482 | //----------------------------------------------------------------- 483 | static void thread_switch(void) 484 | { 485 | // Get the current run count 486 | uint32_t oldRuncount = _current_thread->run_count; 487 | 488 | // Cause context switch 489 | cpu_context_switch(); 490 | 491 | // In-order to get back to this point, we must have been 492 | // picked by thread_pick() and the run-count incremented. 493 | OS_ASSERT(oldRuncount != (_current_thread->run_count)); 494 | 495 | // This thread must be in the run list otherwise something has gone wrong! 496 | OS_ASSERT(_current_thread->state == THREAD_RUNABLE); 497 | } 498 | //----------------------------------------------------------------- 499 | // thread_load_context: Find highest priority run-able thread to run 500 | //----------------------------------------------------------------- 501 | CRITICALFUNC void thread_load_context(int preempt) 502 | { 503 | struct thread * pThread; 504 | 505 | // If non pre-emptive scheduler, don't change threads for pre-emption. 506 | // (Don't change context until the current thread is non-runnable) 507 | #ifdef CONFIG_RTOS_COOPERATIVE_SCHEDULING 508 | if (preempt && _current_thread->state == THREAD_RUNABLE) 509 | return; 510 | #endif 511 | 512 | #ifdef CONFIG_RTOS_MEASURE_THREAD_TIME 513 | // How long was this thread scheduled for? 514 | if (_current_thread->run_start != 0) 515 | _current_thread->run_time += cpu_timediff(cpu_timenow(), _current_thread->run_start); 516 | #endif 517 | 518 | // Now pick the highest thread that can be run and restore it's context. 519 | pThread = thread_pick(); 520 | 521 | #ifdef CONFIG_RTOS_MEASURE_THREAD_TIME 522 | // Take a snapshot of the system clock when thread selected 523 | pThread->run_start = cpu_timenow(); 524 | 525 | // Time=0 has a special meaning! 526 | if (pThread->run_start == 0) 527 | pThread->run_start = 1; 528 | #endif 529 | 530 | // Load new thread's context 531 | _current_thread = pThread; 532 | } 533 | //----------------------------------------------------------------- 534 | // thread_current: Get the current thread that is active! 535 | //----------------------------------------------------------------- 536 | struct thread* thread_current() 537 | { 538 | return _current_thread; 539 | } 540 | //----------------------------------------------------------------- 541 | // thread_pick: Pick the highest priority runable thread 542 | // NOTE: Must be called within critical protection region 543 | //----------------------------------------------------------------- 544 | static CRITICALFUNC struct thread* thread_pick(void) 545 | { 546 | struct thread *pThread; 547 | struct link_node *node; 548 | 549 | // If we have a current running task and if the current thread 550 | // is still run-able, put it in the correct position in the list. 551 | if (_current_thread && _current_thread->state == THREAD_RUNABLE) 552 | { 553 | // Remove it from the run list 554 | list_remove(&_thread_runnable, &_current_thread->node); 555 | // and re-insert at appropriate position in run list 556 | // based on thread priority. 557 | // This will be after all the other threads at the same 558 | // priority level, hence allowing round robin execution 559 | // of other threads with the same priority level. 560 | thread_insert_priority(&_thread_runnable, _current_thread); 561 | } 562 | 563 | // Get the first runable thread 564 | node = list_first(&_thread_runnable); 565 | OS_ASSERT(node != NULL); 566 | 567 | pThread = list_entry(node, struct thread, node); 568 | 569 | // We should have found a task to run as long as there is at least one 570 | // task on the run list (there should be as this is why we have the idle 571 | // task!). 572 | OS_ASSERT(pThread != NULL); 573 | OS_ASSERT(pThread->checkword == THREAD_CHECK_WORD); 574 | OS_ASSERT(pThread->state == THREAD_RUNABLE); 575 | 576 | pThread->run_count++; 577 | 578 | // Total thread context switches / timer ticks have occurred 579 | _thread_picks++; 580 | 581 | return pThread; 582 | } 583 | //----------------------------------------------------------------- 584 | // thread_tick: Kernel tick handler 585 | // NOTE: Must be called within critical protection region (or INT) 586 | //----------------------------------------------------------------- 587 | CRITICALFUNC void thread_tick(void) 588 | { 589 | struct thread *pThread = NULL; 590 | struct link_node *node; 591 | #ifdef CONFIG_RTOS_ABSOLUTE_TIME 592 | uint64_t current_time = cpu_timenow(); 593 | #endif 594 | 595 | // Get the first sleeping thread 596 | node = list_first(&_thread_sleeping); 597 | pThread = list_entry(node, struct thread, node); 598 | 599 | #ifndef CONFIG_RTOS_ABSOLUTE_TIME 600 | // Decrement a tick from the first item in the list 601 | if (pThread && pThread->wait_delta) 602 | pThread->wait_delta--; 603 | #endif 604 | 605 | // Iterate through list of sleeping threads 606 | while (pThread != NULL) 607 | { 608 | OS_ASSERT(pThread->checkword == THREAD_CHECK_WORD); 609 | OS_ASSERT(pThread->state == THREAD_SLEEPING); 610 | 611 | // Has this item timed out? 612 | #ifdef CONFIG_RTOS_ABSOLUTE_TIME 613 | if (current_time >= pThread->wakeup_time) 614 | #else 615 | if (pThread->wait_delta == 0) 616 | #endif 617 | { 618 | // Remove from the sleep list 619 | list_remove(&_thread_sleeping, &pThread->node); 620 | 621 | // Add to the run list and mark runable 622 | pThread->state = THREAD_RUNABLE; 623 | thread_insert_priority(&_thread_runnable, pThread); 624 | 625 | // Get next node (new first node) 626 | node = list_first(&_thread_sleeping); 627 | pThread = list_entry(node, struct thread, node); 628 | } 629 | // Non-zero timeout remaining, end of timed out items 630 | else 631 | break; 632 | } 633 | 634 | // Thats all, thread_load_context() will do the pick 635 | // of the highest priority runable task... 636 | 637 | _tick_count++; 638 | } 639 | //----------------------------------------------------------------- 640 | // thread_tick_count: Get the tick count for the RTOS 641 | //----------------------------------------------------------------- 642 | uint32_t thread_tick_count(void) 643 | { 644 | return _tick_count; 645 | } 646 | //----------------------------------------------------------------- 647 | // thread_func: Wrapper for thread entry point 648 | //----------------------------------------------------------------- 649 | static void thread_func(void *pThd) 650 | { 651 | struct thread *pThread = (struct thread *)pThd; 652 | void *ret_arg; 653 | 654 | OS_ASSERT(pThread); 655 | OS_ASSERT(pThread->checkword == THREAD_CHECK_WORD); 656 | 657 | // Execute thread function 658 | ret_arg = pThread->thread_func(pThread->thread_arg); 659 | 660 | // Now thread has exited, call thread_suicide! 661 | thread_suicide(pThread, ret_arg); 662 | 663 | // We should never reach here! 664 | OS_PANIC("Should not be here"); 665 | } 666 | //----------------------------------------------------------------- 667 | // thread_block: Block specified thread from executing 668 | // WARNING: Call within critical section! 669 | //----------------------------------------------------------------- 670 | void thread_block(struct thread *pThread) 671 | { 672 | OS_ASSERT(pThread->checkword == THREAD_CHECK_WORD); 673 | OS_ASSERT(pThread->state == THREAD_RUNABLE); 674 | 675 | // Mark thread as blocked 676 | pThread->state = THREAD_BLOCKED; 677 | 678 | // Remove from the run list 679 | list_remove(&_thread_runnable, &pThread->node); 680 | 681 | // Add to the blocked list 682 | list_insert_last(&_thread_blocked, &pThread->node); 683 | 684 | // Switch context to the new highest priority thread 685 | thread_switch(); 686 | } 687 | //----------------------------------------------------------------- 688 | // thread_unblock_int: Unblock specified thread. Internal function. 689 | // Manipulates the ready/blocked/sleeping lists only. 690 | // WARNING: Call within critical section! 691 | //----------------------------------------------------------------- 692 | static void thread_unblock_int(struct thread *pThread) 693 | { 694 | // WARNING: There is no gaurantee that unblock is not called 695 | // on a thread that is already runable. 696 | // This is due to a timed semaphore timing out, being made 697 | // runable again but that thread not being scheduled prior 698 | // to the post operation which will unblock it... 699 | 700 | // Is thread sleeping (i.e doing a timed pend using thread_sleep)? 701 | if (pThread->state == THREAD_SLEEPING) 702 | { 703 | #ifndef CONFIG_RTOS_ABSOLUTE_TIME 704 | // Is there another thread after this in the delta sleeping list? 705 | struct link_node *node = list_next(&_thread_sleeping, &pThread->node); 706 | if (node) 707 | { 708 | struct thread *pNextThread = list_entry(node, struct thread, node); 709 | 710 | // Add current item's remaining time to next 711 | pNextThread->wait_delta += pThread->wait_delta; 712 | } 713 | 714 | // Clear the sleep timer 715 | pThread->wait_delta = 0; 716 | #endif 717 | // Remove from the sleeping list 718 | list_remove(&_thread_sleeping, &pThread->node); 719 | } 720 | // Is the thread in the blocked list 721 | else if (pThread->state == THREAD_BLOCKED) 722 | { 723 | // Remove from the blocked list 724 | list_remove(&_thread_blocked, &pThread->node); 725 | } 726 | // Already in the run list, exit! 727 | else if (pThread->state == THREAD_RUNABLE) 728 | return ; 729 | 730 | // Mark thread as run-able 731 | pThread->state = THREAD_RUNABLE; 732 | 733 | // Add to the run list 734 | thread_insert_priority(&_thread_runnable, pThread); 735 | } 736 | //----------------------------------------------------------------- 737 | // thread_unblock: Unblock specified thread / enable execution 738 | // WARNING: Call within critical section! 739 | //----------------------------------------------------------------- 740 | void thread_unblock(struct thread *pThread) 741 | { 742 | OS_ASSERT(pThread->checkword == THREAD_CHECK_WORD); 743 | 744 | // Make sure thread is now in the run list 745 | thread_unblock_int(pThread); 746 | 747 | // If un-blocked thread is higher priority than this thread 748 | // then switch context to the new highest priority thread 749 | if (pThread->priority > _current_thread->priority) 750 | thread_switch(); 751 | } 752 | //----------------------------------------------------------------- 753 | // thread_unblock_irq: Unblock thread from IRQ 754 | //----------------------------------------------------------------- 755 | void thread_unblock_irq(struct thread *pThread) 756 | { 757 | // Critical section should not be required, but for sanity 758 | int cr = critical_start(); 759 | 760 | OS_ASSERT(pThread->checkword == THREAD_CHECK_WORD); 761 | 762 | // Make sure thread is now in the run list 763 | thread_unblock_int(pThread); 764 | 765 | // Schedule a context switch to occur after IRQ completes 766 | cpu_context_switch_irq(); 767 | 768 | critical_end(cr); 769 | } 770 | //----------------------------------------------------------------- 771 | // thread_insert_priority: Insert thread into list in priority order 772 | //----------------------------------------------------------------- 773 | static CRITICALFUNC void thread_insert_priority(struct link_list *pList, struct thread *pInsertNode) 774 | { 775 | struct link_node *node; 776 | 777 | OS_ASSERT(pList != NULL); 778 | OS_ASSERT(pInsertNode != NULL); 779 | 780 | // No items in the queue, insert at the head 781 | if (list_is_empty(pList)) 782 | list_insert_first(pList, &pInsertNode->node); 783 | else 784 | { 785 | // Iterate through list and add in order of priority 786 | // NOTE: Duplicates will be added to end of list of duplicate 787 | // threads priorities. 788 | list_for_each(pList, node) 789 | { 790 | // Get the thread item 791 | struct thread* thread = list_entry(node, struct thread, node); 792 | 793 | // Is threads priority lower than this thread? 794 | if (pInsertNode->priority > thread->priority) 795 | { 796 | // Insert before this node 797 | list_insert_before(pList, node, &pInsertNode->node); 798 | break; 799 | } 800 | 801 | // End of the list reached and node not inserted yet 802 | if (list_next(pList, node) == NULL) 803 | { 804 | // Insert after current last node 805 | list_insert_after(pList, node, &pInsertNode->node); 806 | break; 807 | } 808 | } 809 | } 810 | } 811 | //----------------------------------------------------------------- 812 | // thread_idle_task: Idle task function 813 | //----------------------------------------------------------------- 814 | static void *thread_idle_task(void* arg) 815 | { 816 | while (1) 817 | cpu_idle(); 818 | 819 | return NULL; 820 | } 821 | //----------------------------------------------------------------- 822 | // thread_print_thread: Print thread details to OS_PRINTF 823 | //----------------------------------------------------------------- 824 | static void thread_print_thread(int idx, struct thread *pThread, uint32_t sleepTime, int (*os_printf)(const char* ctrl1, ... )) 825 | { 826 | char stateChar; 827 | 828 | os_printf("%d:\t", idx+1); 829 | os_printf("|%10.10s|\t", pThread->name); 830 | os_printf("%d\t", pThread->priority); 831 | 832 | if (pThread == _current_thread) 833 | stateChar = '*'; 834 | else 835 | { 836 | switch (pThread->state) 837 | { 838 | case THREAD_RUNABLE: 839 | stateChar = 'R'; 840 | break; 841 | case THREAD_SLEEPING: 842 | stateChar = 'S'; 843 | break; 844 | case THREAD_BLOCKED: 845 | stateChar = 'B'; 846 | break; 847 | case THREAD_DEAD: 848 | stateChar = 'X'; 849 | break; 850 | default: 851 | stateChar = 'U'; 852 | break; 853 | } 854 | } 855 | 856 | os_printf("%c\t", stateChar); 857 | os_printf("%ld\t", sleepTime); 858 | os_printf("%ld\t", pThread->run_count); 859 | os_printf("%ld\r\n", cpu_thread_stack_free(&pThread->tcb)); 860 | } 861 | //----------------------------------------------------------------- 862 | // thread_dump_list: Dump thread list via specified printf 863 | //----------------------------------------------------------------- 864 | void thread_dump_list(int (*os_printf)(const char* ctrl1, ... )) 865 | { 866 | struct thread *pThread; 867 | struct link_node *node; 868 | #ifdef CONFIG_RTOS_ABSOLUTE_TIME 869 | uint64_t current_time = cpu_timenow(); 870 | #else 871 | uint32_t sleepTimeTotal = 0; 872 | #endif 873 | int idx = 0; 874 | 875 | int cr = critical_start(); 876 | 877 | os_printf("Thread Dump:\r\n"); 878 | os_printf("Num Name Pri State Sleep Runs Free Stack\r\n"); 879 | 880 | // Print all runable threads 881 | pThread = _thread_list_all; 882 | while (pThread != NULL) 883 | { 884 | if (pThread->state == THREAD_RUNABLE) 885 | thread_print_thread(idx++, pThread, 0, os_printf); 886 | pThread = pThread->next_all; 887 | } 888 | 889 | // Print sleeping threads 890 | node = list_first(&_thread_sleeping); 891 | while (node != NULL) 892 | { 893 | pThread = list_entry(node, struct thread, node); 894 | 895 | #ifdef CONFIG_RTOS_ABSOLUTE_TIME 896 | thread_print_thread(idx++, pThread, pThread->wakeup_time - current_time, os_printf); 897 | #else 898 | sleepTimeTotal += pThread->wait_delta; 899 | thread_print_thread(idx++, pThread, sleepTimeTotal, os_printf); 900 | #endif 901 | 902 | node = list_next(&_thread_sleeping, node); 903 | } 904 | 905 | // Print blocked threads 906 | pThread = _thread_list_all; 907 | while (pThread != NULL) 908 | { 909 | if (pThread->state == THREAD_BLOCKED) 910 | thread_print_thread(idx++, pThread, 0, os_printf); 911 | pThread = pThread->next_all; 912 | } 913 | 914 | // Print dead threads 915 | pThread = _thread_list_all; 916 | while (pThread != NULL) 917 | { 918 | if (pThread->state == THREAD_DEAD) 919 | thread_print_thread(idx++, pThread, 0, os_printf); 920 | pThread = pThread->next_all; 921 | } 922 | 923 | critical_end(cr); 924 | } 925 | //----------------------------------------------------------------- 926 | // thread_get_cpu_load: Calculate CPU load percentage. 927 | // Higher = heavier system task load. 928 | // Requires CONFIG_RTOS_MEASURE_THREAD_TIME to be defined along with 929 | // appropriate system clock/time measurement functions. 930 | //----------------------------------------------------------------- 931 | #ifdef CONFIG_RTOS_MEASURE_THREAD_TIME 932 | int thread_get_cpu_load(void) 933 | { 934 | struct thread *pThread; 935 | uint32_t idle_time = 0; 936 | uint32_t total_time = 0; 937 | 938 | int cr = critical_start(); 939 | 940 | // Walk the thread list and calculate sum of total time spent in all threads 941 | pThread = _thread_list_all; 942 | while (pThread != NULL) 943 | { 944 | // Idle task 945 | if (pThread == &_idle_task) 946 | { 947 | OS_ASSERT( idle_time == 0 ); 948 | idle_time = pThread->run_time; 949 | total_time += pThread->run_time; 950 | } 951 | // Other tasks 952 | else 953 | total_time += pThread->run_time; 954 | 955 | // Clear time once read 956 | pThread->run_time = 0; 957 | 958 | // Next thread in the list 959 | pThread = pThread->next_all; 960 | } 961 | 962 | critical_end(cr); 963 | 964 | // Scale if large numbers 965 | if (idle_time > (1 << 24)) 966 | { 967 | idle_time >>= 8; 968 | total_time >>= 8; 969 | } 970 | 971 | if (total_time) 972 | return 100 - ((idle_time * 100) / total_time); 973 | else 974 | return 0; 975 | } 976 | #endif 977 | //----------------------------------------------------------------- 978 | // thread_get_first_thread: 979 | //----------------------------------------------------------------- 980 | struct thread *thread_get_first_thread(void) 981 | { 982 | return _thread_list_all; 983 | } 984 | -------------------------------------------------------------------------------- /kernel/thread.h: -------------------------------------------------------------------------------- 1 | #ifndef __THREAD_H__ 2 | #define __THREAD_H__ 3 | 4 | //----------------------------------------------------------------- 5 | // Includes 6 | //----------------------------------------------------------------- 7 | #include "cpu_thread.h" 8 | #include "list.h" 9 | 10 | //----------------------------------------------------------------- 11 | // Basic Types 12 | //----------------------------------------------------------------- 13 | #ifndef CONFIG_RTOS_HAS_NO_STDINT 14 | #include 15 | #else 16 | typedef unsigned char uint8_t; 17 | typedef signed char int8_t; 18 | typedef unsigned short uint16_t; 19 | typedef signed short int16_t; 20 | typedef unsigned long uint32_t; 21 | typedef signed long int32_t; 22 | typedef unsigned long long uint64_t; 23 | typedef signed long long int64_t; 24 | #endif 25 | 26 | //----------------------------------------------------------------- 27 | // Standard Defines 28 | // (should already be available if standard header files are available) 29 | //----------------------------------------------------------------- 30 | #ifndef NULL 31 | #define NULL 0 32 | #endif 33 | 34 | #ifndef FALSE 35 | #define FALSE 0 36 | #endif 37 | 38 | #ifndef TRUE 39 | #define TRUE 1 40 | #endif 41 | 42 | //----------------------------------------------------------------- 43 | // Defines 44 | //----------------------------------------------------------------- 45 | 46 | // Max name length for a thread 47 | #define THREAD_NAME_LEN 16 48 | 49 | // Idle task priority (do not change) 50 | #define THREAD_IDLE_PRIO -1 51 | 52 | // Min thread priority number 53 | #define THREAD_MIN_PRIO 0 54 | 55 | // Max thread priority number 56 | #define THREAD_MAX_PRIO 10 57 | 58 | // Min interrupt priority 59 | #define THREAD_INT_PRIO (THREAD_MAX_PRIO + 1) 60 | 61 | // Thread structure checkword 62 | #define THREAD_CHECK_WORD 0xFEADDE01 63 | 64 | // Thread sleep arg used to yield 65 | #define THREAD_YIELD 0 66 | 67 | //----------------------------------------------------------------- 68 | // Enums 69 | //----------------------------------------------------------------- 70 | 71 | // Thread state enumeration 72 | typedef enum eThreadState 73 | { 74 | THREAD_RUNABLE, 75 | THREAD_SLEEPING, 76 | THREAD_BLOCKED, 77 | THREAD_DEAD 78 | } tThreadState; 79 | 80 | //----------------------------------------------------------------- 81 | // Types 82 | //----------------------------------------------------------------- 83 | struct thread 84 | { 85 | // CPU specific thread state 86 | struct cpu_tcb tcb; 87 | 88 | // Unique thread ID 89 | int thread_id; 90 | 91 | // Thread name (used in debug output) 92 | char name[THREAD_NAME_LEN]; 93 | 94 | // Thread priority 95 | int priority; 96 | 97 | // state (Run-able, blocked or sleeping) 98 | tThreadState state; 99 | 100 | #ifdef CONFIG_RTOS_ABSOLUTE_TIME 101 | // Sleep wake time (absolute) 102 | uint64_t wakeup_time; 103 | #else 104 | // Sleep time remaining (ticks) (delta) 105 | uint32_t wait_delta; 106 | #endif 107 | 108 | // Thread run count 109 | uint32_t run_count; 110 | 111 | #ifdef CONFIG_RTOS_MEASURE_THREAD_TIME 112 | // Measure time each thread is active for? 113 | uint32_t run_time; 114 | uint32_t run_start; 115 | #endif 116 | 117 | // Thread function 118 | void *(*thread_func)(void *); 119 | void *thread_arg; 120 | 121 | // Run/Sleep/Blocked list node 122 | struct link_node node; 123 | 124 | // next thread in complete name list 125 | struct thread *next_all; 126 | 127 | // Blocking node items 128 | struct link_node blocking_node; 129 | void* unblocking_arg; 130 | 131 | // List of threads pending on thread exit 132 | struct link_list join_list; 133 | void *exit_value; 134 | 135 | // Thread check word 136 | uint32_t checkword; 137 | }; 138 | 139 | //----------------------------------------------------------------- 140 | // Macros 141 | //----------------------------------------------------------------- 142 | #define THREAD_DECL(id, stack_size) \ 143 | static struct thread thread_ ## id; \ 144 | static stk_t stack_ ## id[stack_size] 145 | 146 | #define THREAD_INIT(id, name, func, arg, prio) \ 147 | thread_init(& thread_ ## id, name, prio, func, (void*)(arg), stack_ ## id, sizeof(stack_ ## id) / sizeof(stk_t)) 148 | 149 | //----------------------------------------------------------------- 150 | // Prototypes 151 | //----------------------------------------------------------------- 152 | 153 | // Initialise the RTOS kernel 154 | int thread_kernel_init(void); 155 | 156 | // Start the RTOS kernel 157 | void thread_kernel_run(void); 158 | 159 | // Init thread (immediately run-able) 160 | int thread_init(struct thread *pThread, const char *name, int pri, void *(*f)(void *), void *arg, void *stack, uint32_t stack_size); 161 | 162 | // Init thread with specified start state 163 | int thread_init_ex(struct thread *pThread, const char *name, int pri, void *(*f)(void *), void *arg, void *stack, uint32_t stack_size, tThreadState initial_state); 164 | 165 | // Kill thread and remove from all thread lists. 166 | // Once complete, thread data/stack will not be accessed again by RTOS. 167 | // You cannot kill a thread from itself, use thread_suicide instead. 168 | int thread_kill(struct thread *pThread); 169 | 170 | // Allows a thread to self terminate 171 | void thread_suicide(struct thread *pThread, void *exit_arg); 172 | 173 | // Wait for thread to exit 174 | void* thread_join(struct thread *pThread); 175 | 176 | // Sleep thread for x time units 177 | void thread_sleep(uint32_t time_units); 178 | 179 | // Extended thread sleep API 180 | void thread_sleep_thread(struct thread *pSleepThread, uint32_t time_units); 181 | void thread_sleep_cancel(struct thread *pThread); 182 | 183 | // Get current thread 184 | struct thread* thread_current(void); 185 | 186 | // Kernel tick handler 187 | void thread_tick(void); 188 | 189 | // Get the tick count for the RTOS 190 | uint32_t thread_tick_count(void); 191 | 192 | // Block specified thread 193 | void thread_block(struct thread *pThread); 194 | 195 | // Unblock specified thread 196 | void thread_unblock(struct thread *pThread); 197 | 198 | // Unblock thread from running (called from ISR context) 199 | void thread_unblock_irq(struct thread *pThread); 200 | 201 | // Dump thread list via specified printf 202 | void thread_dump_list(int (*os_printf)(const char* ctrl1, ... )); 203 | 204 | // Calculate CPU load percentage 205 | int thread_get_cpu_load(void); 206 | 207 | // Find highest priority run-able thread to run 208 | void thread_load_context(int preempt); 209 | 210 | // Get list of all system threads 211 | struct thread * thread_get_first_thread(void); 212 | 213 | #endif 214 | 215 | -------------------------------------------------------------------------------- /testcases/test.h: -------------------------------------------------------------------------------- 1 | #ifndef __TEST_H__ 2 | #define __TEST_H__ 3 | 4 | #include "kernel/critical.h" 5 | #include "kernel/os_assert.h" 6 | #include "kernel/list.h" 7 | #include "kernel/thread.h" 8 | #include "kernel/mutex.h" 9 | #include "kernel/semaphore.h" 10 | #include "kernel/event.h" 11 | #include "kernel/mutex.h" 12 | #include "kernel/mailbox.h" 13 | 14 | #ifdef __unix__ 15 | #include 16 | #include 17 | #else 18 | #include "sim_ctrl.h" 19 | #endif 20 | 21 | #ifndef __unix__ 22 | static inline void exit(int exitcode) 23 | { 24 | sim_exit(exitcode); 25 | } 26 | #endif 27 | 28 | #endif -------------------------------------------------------------------------------- /testcases/test_basic0.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | 3 | //----------------------------------------------------------------- 4 | // Defines: 5 | //----------------------------------------------------------------- 6 | 7 | //----------------------------------------------------------------- 8 | // Locals: 9 | //----------------------------------------------------------------- 10 | THREAD_DECL(thread0, 1024); 11 | THREAD_DECL(thread1, 1024); 12 | THREAD_DECL(thread2, 1024); 13 | THREAD_DECL(thread3, 1024); 14 | 15 | static volatile int flag0 = 0; 16 | static volatile int flag1 = 0; 17 | static volatile int flag2 = 0; 18 | static volatile int flag3 = 0; 19 | 20 | //----------------------------------------------------------------- 21 | // thread_func 22 | //----------------------------------------------------------------- 23 | static void* thread_func(void *arg) 24 | { 25 | int *flag = (int*) arg; 26 | printf("thread!\n"); 27 | 28 | *flag = 1; 29 | 30 | // Busy wait, thread will be preempted on timeslice interval 31 | // and round robin interleaved with other threads at same prio 32 | while (1); 33 | 34 | return NULL; 35 | } 36 | //----------------------------------------------------------------- 37 | // Test Thread Function: 38 | //----------------------------------------------------------------- 39 | void testcase(void * a) 40 | { 41 | THREAD_INIT(thread0, "thread0", thread_func, &flag0, 0); 42 | THREAD_INIT(thread1, "thread1", thread_func, &flag1, 0); 43 | THREAD_INIT(thread2, "thread2", thread_func, &flag2, 0); 44 | THREAD_INIT(thread3, "thread3", thread_func, &flag3, 0); 45 | 46 | // Deschedule for long enough for other threads to complete 47 | thread_sleep(4); 48 | 49 | OS_ASSERT(flag0 == 1); 50 | OS_ASSERT(flag1 == 1); 51 | OS_ASSERT(flag2 == 1); 52 | OS_ASSERT(flag3 == 1); 53 | 54 | exit(0); 55 | } 56 | -------------------------------------------------------------------------------- /testcases/test_basic1.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | 3 | //----------------------------------------------------------------- 4 | // Defines: 5 | //----------------------------------------------------------------- 6 | 7 | //----------------------------------------------------------------- 8 | // Locals: 9 | //----------------------------------------------------------------- 10 | THREAD_DECL(thread0, 1024); 11 | THREAD_DECL(thread1, 1024); 12 | THREAD_DECL(thread2, 1024); 13 | THREAD_DECL(thread3, 1024); 14 | 15 | static volatile int flag0 = 0; 16 | static volatile int flag1 = 0; 17 | static volatile int flag2 = 0; 18 | static volatile int flag3 = 0; 19 | 20 | //----------------------------------------------------------------- 21 | // thread_func 22 | //----------------------------------------------------------------- 23 | static void* thread_func(void *arg) 24 | { 25 | int *flag = (int*) arg; 26 | printf("thread!\n"); 27 | 28 | *flag = 1; 29 | 30 | // Busy wait, thread will be preempted on timeslice interval 31 | // and round robin interleaved with other threads at same prio 32 | while (1); 33 | 34 | return NULL; 35 | } 36 | //----------------------------------------------------------------- 37 | // Test Thread Function: 38 | //----------------------------------------------------------------- 39 | void testcase(void * a) 40 | { 41 | THREAD_INIT(thread0, "thread0", thread_func, &flag0, 1); 42 | THREAD_INIT(thread1, "thread1", thread_func, &flag1, 1); 43 | THREAD_INIT(thread2, "thread2", thread_func, &flag2, 0); 44 | THREAD_INIT(thread3, "thread3", thread_func, &flag3, 0); 45 | 46 | // Deschedule for long enough for thread 0 & 1 to run 47 | // Thread 2 & 3 should never run as they are low priority 48 | // and thread 0 & 1 are busy waiting... 49 | thread_sleep(4); 50 | 51 | OS_ASSERT(flag0 == 1); 52 | OS_ASSERT(flag1 == 1); 53 | OS_ASSERT(flag2 == 0); 54 | OS_ASSERT(flag3 == 0); 55 | 56 | exit(0); 57 | } 58 | -------------------------------------------------------------------------------- /testcases/test_basic2.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | 3 | //----------------------------------------------------------------- 4 | // Defines: 5 | //----------------------------------------------------------------- 6 | 7 | //----------------------------------------------------------------- 8 | // Locals: 9 | //----------------------------------------------------------------- 10 | THREAD_DECL(thread0, 1024); 11 | THREAD_DECL(thread1, 1024); 12 | 13 | static volatile int _counter = 0; 14 | 15 | //----------------------------------------------------------------- 16 | // thread_func 17 | //----------------------------------------------------------------- 18 | static void* thread_func(void *arg) 19 | { 20 | int last; 21 | 22 | // Perform this operation in a critical section so that the thread 23 | // switch points are under our control... 24 | int cr = critical_start(); 25 | 26 | while (1) 27 | { 28 | _counter++; 29 | last = _counter; 30 | 31 | // Yield to another thread on the run list at the same priority 32 | thread_sleep(0); 33 | 34 | if (_counter > 100) 35 | break; 36 | 37 | OS_ASSERT(last != _counter); 38 | } 39 | 40 | critical_end(cr); 41 | 42 | return NULL; 43 | } 44 | //----------------------------------------------------------------- 45 | // Test Thread Function: 46 | //----------------------------------------------------------------- 47 | void testcase(void * a) 48 | { 49 | THREAD_INIT(thread0, "thread0", thread_func, NULL, 0); 50 | THREAD_INIT(thread1, "thread1", thread_func, NULL, 0); 51 | 52 | // Check for round robin scheduling for threads on the same priority 53 | thread_sleep(6); 54 | 55 | exit(0); 56 | } 57 | -------------------------------------------------------------------------------- /testcases/test_join0.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | 3 | //----------------------------------------------------------------- 4 | // Defines: 5 | //----------------------------------------------------------------- 6 | 7 | //----------------------------------------------------------------- 8 | // Locals: 9 | //----------------------------------------------------------------- 10 | THREAD_DECL(thread0, 1024); 11 | 12 | //----------------------------------------------------------------- 13 | // thread_func 14 | //----------------------------------------------------------------- 15 | static void* thread_func(void *arg) 16 | { 17 | OS_ASSERT(arg == NULL); 18 | return (void *)1; 19 | } 20 | //----------------------------------------------------------------- 21 | // Test Thread Function: (Max priority) 22 | //----------------------------------------------------------------- 23 | void testcase(void * a) 24 | { 25 | void *res; 26 | 27 | THREAD_INIT(thread0, "thread0", thread_func, NULL, 0); 28 | 29 | // Higher priority thread spawns low priority thread 30 | // then deschedules waiting for completion. 31 | // Low prio thread then runs and exits returning a value. 32 | res = thread_join(&thread_thread0); 33 | OS_ASSERT(res == (void*)1); 34 | 35 | exit(0); 36 | } 37 | -------------------------------------------------------------------------------- /testcases/test_join1.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | 3 | //----------------------------------------------------------------- 4 | // Defines: 5 | //----------------------------------------------------------------- 6 | 7 | //----------------------------------------------------------------- 8 | // Locals: 9 | //----------------------------------------------------------------- 10 | THREAD_DECL(thread0, 1024); 11 | THREAD_DECL(thread1, 1024); 12 | 13 | //----------------------------------------------------------------- 14 | // thread_func 15 | //----------------------------------------------------------------- 16 | static void* thread_func(void *arg) 17 | { 18 | return arg; 19 | } 20 | //----------------------------------------------------------------- 21 | // Test Thread Function: (Max priority) 22 | //----------------------------------------------------------------- 23 | void testcase(void * a) 24 | { 25 | void *res; 26 | 27 | THREAD_INIT(thread0, "thread0", thread_func, (void *)0, 0); 28 | THREAD_INIT(thread1, "thread1", thread_func, (void *)1, 0); 29 | 30 | // One thread waiting on multiple low priority threads 31 | // yielding so that the second will have already run and 32 | // exited, check checking the result 33 | res = thread_join(&thread_thread0); 34 | OS_ASSERT(res == (void*)0); 35 | 36 | thread_sleep(2); 37 | 38 | res = thread_join(&thread_thread1); 39 | OS_ASSERT(res == (void*)1); 40 | 41 | exit(0); 42 | } 43 | -------------------------------------------------------------------------------- /testcases/test_kill0.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | 3 | //----------------------------------------------------------------- 4 | // Defines: 5 | //----------------------------------------------------------------- 6 | 7 | //----------------------------------------------------------------- 8 | // Locals: 9 | //----------------------------------------------------------------- 10 | THREAD_DECL(thread0, 8192); 11 | THREAD_DECL(thread1, 8192); 12 | 13 | static volatile int _flag = 0; 14 | 15 | //----------------------------------------------------------------- 16 | // thread_func 17 | //----------------------------------------------------------------- 18 | static void* thread_func(void *arg) 19 | { 20 | if (arg == (void*)0) 21 | thread_sleep(5); 22 | else 23 | { 24 | _flag = 1; 25 | thread_sleep(10); 26 | _flag = 2; 27 | } 28 | 29 | return NULL; 30 | } 31 | //----------------------------------------------------------------- 32 | // Test Thread Function: 33 | //----------------------------------------------------------------- 34 | void testcase(void * a) 35 | { 36 | THREAD_INIT(thread0, "thread0", thread_func, 0, 0); 37 | THREAD_INIT(thread1, "thread1", thread_func, 1, 0); 38 | 39 | thread_sleep(1); 40 | OS_ASSERT(_flag == 1); 41 | thread_kill(&thread_thread0); 42 | 43 | thread_sleep(7); 44 | OS_ASSERT(_flag == 1); 45 | 46 | thread_sleep(4); 47 | OS_ASSERT(_flag == 2); 48 | 49 | exit(0); 50 | } 51 | -------------------------------------------------------------------------------- /testcases/test_mtx0.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | 3 | //----------------------------------------------------------------- 4 | // Defines: 5 | //----------------------------------------------------------------- 6 | 7 | //----------------------------------------------------------------- 8 | // Locals: 9 | //----------------------------------------------------------------- 10 | THREAD_DECL(thread0, 1024); 11 | THREAD_DECL(thread1, 1024); 12 | 13 | static struct mutex _mtx0; 14 | static volatile int _counter = 0; 15 | 16 | //----------------------------------------------------------------- 17 | // thread0_func 18 | //----------------------------------------------------------------- 19 | static void* thread0_func(void *arg) 20 | { 21 | int last; 22 | 23 | mutex_lock(&_mtx0); 24 | 25 | OS_ASSERT(_counter == 0); 26 | 27 | while (_counter < 10) 28 | { 29 | last = _counter; 30 | thread_sleep(1); 31 | 32 | OS_ASSERT(last == _counter); 33 | 34 | _counter++; 35 | } 36 | 37 | mutex_unlock(&_mtx0); 38 | 39 | return NULL; 40 | } 41 | //----------------------------------------------------------------- 42 | // thread1_func 43 | //----------------------------------------------------------------- 44 | static void* thread1_func(void *arg) 45 | { 46 | int last; 47 | 48 | mutex_lock(&_mtx0); 49 | 50 | OS_ASSERT(_counter == 10); 51 | 52 | _counter++; 53 | 54 | mutex_unlock(&_mtx0); 55 | 56 | return NULL; 57 | } 58 | //----------------------------------------------------------------- 59 | // Test Thread Function: (Max priority) 60 | //----------------------------------------------------------------- 61 | void testcase(void * a) 62 | { 63 | // Non-recursive mutex 64 | mutex_init(&_mtx0, 0); 65 | 66 | // Low priority thead which pends on a semaphore 67 | THREAD_INIT(thread0, "thread0", thread0_func, NULL, 1); 68 | THREAD_INIT(thread1, "thread1", thread1_func, NULL, 0); 69 | 70 | // Block on the lowest priority thread 71 | thread_join(&thread_thread1); 72 | 73 | OS_ASSERT(_counter == 11); 74 | 75 | exit(0); 76 | } 77 | -------------------------------------------------------------------------------- /testcases/test_mtx1.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | 3 | //----------------------------------------------------------------- 4 | // Defines: 5 | //----------------------------------------------------------------- 6 | 7 | //----------------------------------------------------------------- 8 | // Locals: 9 | //----------------------------------------------------------------- 10 | THREAD_DECL(thread0, 1024); 11 | THREAD_DECL(thread1, 1024); 12 | 13 | static struct mutex _mtx0; 14 | static volatile int _counter = 0; 15 | 16 | //----------------------------------------------------------------- 17 | // thread0_func 18 | //----------------------------------------------------------------- 19 | static void* thread0_func(void *arg) 20 | { 21 | int last; 22 | 23 | mutex_lock(&_mtx0); 24 | 25 | OS_ASSERT(_counter == 0); 26 | 27 | // Check that recursive locking works making sure that on 28 | // the inner lock, the protection is still maintained 29 | mutex_lock(&_mtx0); 30 | thread_sleep(1); 31 | mutex_unlock(&_mtx0); 32 | 33 | while (_counter < 10) 34 | { 35 | last = _counter; 36 | thread_sleep(1); 37 | 38 | OS_ASSERT(last == _counter); 39 | 40 | _counter++; 41 | } 42 | 43 | mutex_unlock(&_mtx0); 44 | 45 | return NULL; 46 | } 47 | //----------------------------------------------------------------- 48 | // thread1_func 49 | //----------------------------------------------------------------- 50 | static void* thread1_func(void *arg) 51 | { 52 | int last; 53 | 54 | mutex_lock(&_mtx0); 55 | 56 | OS_ASSERT(_counter == 10); 57 | 58 | _counter++; 59 | 60 | mutex_unlock(&_mtx0); 61 | 62 | return NULL; 63 | } 64 | //----------------------------------------------------------------- 65 | // Test Thread Function: (Max priority) 66 | //----------------------------------------------------------------- 67 | void testcase(void * a) 68 | { 69 | // Recursive mutex 70 | mutex_init(&_mtx0, 1); 71 | 72 | // Low priority thead which pends on a semaphore 73 | THREAD_INIT(thread0, "thread0", thread0_func, NULL, 1); 74 | THREAD_INIT(thread1, "thread1", thread1_func, NULL, 0); 75 | 76 | // Block on the lowest priority thread 77 | thread_join(&thread_thread1); 78 | 79 | OS_ASSERT(_counter == 11); 80 | 81 | exit(0); 82 | } 83 | -------------------------------------------------------------------------------- /testcases/test_sem0.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | 3 | //----------------------------------------------------------------- 4 | // Defines: 5 | //----------------------------------------------------------------- 6 | 7 | //----------------------------------------------------------------- 8 | // Locals: 9 | //----------------------------------------------------------------- 10 | THREAD_DECL(thread0, 1024); 11 | 12 | static struct semaphore _sema0; 13 | static volatile int _flag0 = 0; 14 | 15 | //----------------------------------------------------------------- 16 | // thread_func 17 | //----------------------------------------------------------------- 18 | static void* thread_func(void *arg) 19 | { 20 | struct semaphore *sem = (struct semaphore *)arg; 21 | 22 | semaphore_post(sem); 23 | 24 | _flag0 = 1; 25 | 26 | return NULL; 27 | } 28 | //----------------------------------------------------------------- 29 | // Test Thread Function: (Max priority) 30 | //----------------------------------------------------------------- 31 | void testcase(void * a) 32 | { 33 | uint32_t t0; 34 | uint32_t t1; 35 | int res; 36 | 37 | semaphore_init(&_sema0, 0); 38 | 39 | // Low priority thead which kicks a semaphore 40 | THREAD_INIT(thread0, "thread0", thread_func, &_sema0, 0); 41 | 42 | OS_ASSERT(semaphore_get_value(&_sema0) == 0); 43 | OS_ASSERT(semaphore_try(&_sema0) == 0); 44 | 45 | // Block waiting for semaphore which will enable 46 | // low prio thread to run 47 | semaphore_pend(&_sema0); 48 | 49 | OS_ASSERT(semaphore_get_value(&_sema0) == 0); 50 | OS_ASSERT(semaphore_try(&_sema0) == 0); 51 | 52 | // Thread should have relinshed control during semaphore post 53 | // to this high prio thread 54 | OS_ASSERT(_flag0 == 0); 55 | 56 | // Block waiting for thread to exit 57 | thread_join(&thread_thread0); 58 | 59 | OS_ASSERT(_flag0 == 1); 60 | 61 | t0 = thread_tick_count(); 62 | 63 | // Timed wait on the semaphore (should fail) 64 | res = semaphore_timed_pend(&_sema0, 5); 65 | OS_ASSERT(res == 0); 66 | 67 | t1 = thread_tick_count(); 68 | 69 | OS_ASSERT(((int32_t)(t1 - t0)) >= 5); 70 | 71 | t0 = thread_tick_count(); 72 | 73 | semaphore_post(&_sema0); 74 | 75 | // Timed wait on the semaphore (should complete ok) 76 | res = semaphore_timed_pend(&_sema0, 10); 77 | OS_ASSERT(res == 1); 78 | 79 | t1 = thread_tick_count(); 80 | 81 | OS_ASSERT(((int32_t)(t1 - t0)) <= 1); 82 | 83 | exit(0); 84 | } 85 | -------------------------------------------------------------------------------- /testcases/test_sem1.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | 3 | //----------------------------------------------------------------- 4 | // Defines: 5 | //----------------------------------------------------------------- 6 | 7 | //----------------------------------------------------------------- 8 | // Locals: 9 | //----------------------------------------------------------------- 10 | THREAD_DECL(thread0, 1024); 11 | THREAD_DECL(thread1, 1024); 12 | THREAD_DECL(thread2, 1024); 13 | 14 | static struct semaphore _sema0; 15 | 16 | //----------------------------------------------------------------- 17 | // thread_func 18 | //----------------------------------------------------------------- 19 | static void* thread_func(void *arg) 20 | { 21 | int *flag = (int*) arg; 22 | 23 | semaphore_pend(&_sema0); 24 | 25 | *flag = 1; 26 | 27 | return NULL; 28 | } 29 | //----------------------------------------------------------------- 30 | // Test Thread Function: (Max priority) 31 | //----------------------------------------------------------------- 32 | void testcase(void * a) 33 | { 34 | volatile int flag0 = 0; 35 | volatile int flag1 = 0; 36 | volatile int flag2 = 0; 37 | 38 | semaphore_init(&_sema0, 2); 39 | 40 | // Low priority thead which pends on a semaphore 41 | THREAD_INIT(thread0, "thread0", thread_func, (void*)&flag0, 1); 42 | THREAD_INIT(thread1, "thread1", thread_func, (void*)&flag1, 1); 43 | THREAD_INIT(thread2, "thread2", thread_func, (void*)&flag2, 0); 44 | 45 | OS_ASSERT(semaphore_get_value(&_sema0) == 2); 46 | 47 | // The low priority threads will not have run yet 48 | OS_ASSERT(flag0 == 0); 49 | OS_ASSERT(flag1 == 0); 50 | OS_ASSERT(flag2 == 0); 51 | 52 | thread_sleep(4); 53 | 54 | // The two higher priority threads should grab the semaphores 55 | // but the low priority thread will lose out... 56 | OS_ASSERT(flag0 == 1); 57 | OS_ASSERT(flag1 == 1); 58 | OS_ASSERT(flag2 == 0); 59 | 60 | // Kick the semaphore one more time to give it to the last thread 61 | semaphore_post(&_sema0); 62 | 63 | thread_sleep(1); 64 | 65 | OS_ASSERT(flag0 == 1); 66 | OS_ASSERT(flag1 == 1); 67 | OS_ASSERT(flag2 == 1); 68 | 69 | exit(0); 70 | } 71 | -------------------------------------------------------------------------------- /testcases/test_sem2.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | 3 | //----------------------------------------------------------------- 4 | // Defines: 5 | //----------------------------------------------------------------- 6 | 7 | //----------------------------------------------------------------- 8 | // Locals: 9 | //----------------------------------------------------------------- 10 | THREAD_DECL(thread0, 1024); 11 | THREAD_DECL(thread1, 1024); 12 | 13 | static struct semaphore _sema0; 14 | 15 | //----------------------------------------------------------------- 16 | // thread0_func 17 | //----------------------------------------------------------------- 18 | static void* thread0_func(void *arg) 19 | { 20 | int *flag = (int*) arg; 21 | int res; 22 | 23 | res = semaphore_timed_pend(&_sema0, 5); 24 | OS_ASSERT(res == 1); 25 | 26 | *flag = 1; 27 | 28 | return NULL; 29 | } 30 | //----------------------------------------------------------------- 31 | // thread1_func 32 | //----------------------------------------------------------------- 33 | static void* thread1_func(void *arg) 34 | { 35 | int *flag = (int*) arg; 36 | 37 | // Wait for less time than thread0 is pending on the semaphore 38 | thread_sleep(3); 39 | 40 | // Kick semaphore, which should cause thread 0 to be run 41 | semaphore_post(&_sema0); 42 | 43 | *flag = 1; 44 | 45 | return NULL; 46 | } 47 | //----------------------------------------------------------------- 48 | // Test Thread Function: (Max priority) 49 | //----------------------------------------------------------------- 50 | void testcase(void * a) 51 | { 52 | volatile int flag0 = 0; 53 | volatile int flag1 = 0; 54 | 55 | semaphore_init(&_sema0, 0); 56 | 57 | // Low priority thead which pends on a semaphore 58 | THREAD_INIT(thread0, "thread0", thread0_func, (void*)&flag0, 0); 59 | THREAD_INIT(thread1, "thread1", thread1_func, (void*)&flag1, 1); 60 | 61 | // The low priority threads will not have run yet 62 | OS_ASSERT(flag0 == 0); 63 | OS_ASSERT(flag1 == 0); 64 | 65 | // Block on the lowest priority thread 66 | thread_join(&thread_thread0); 67 | 68 | // Both threads should have run now 69 | OS_ASSERT(flag0 == 1); 70 | OS_ASSERT(flag1 == 1); 71 | 72 | exit(0); 73 | } 74 | -------------------------------------------------------------------------------- /testcases/test_torture0.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | #define assert OS_ASSERT 3 | 4 | THREAD_DECL(thread0, 1024); 5 | THREAD_DECL(thread1, 1024); 6 | 7 | static volatile int func1_count; 8 | static volatile int func2_count; 9 | 10 | static void* func1(void *a); 11 | static void* func2(void *a); 12 | 13 | //----------------------------------------------------------------- 14 | // testcase: 15 | //----------------------------------------------------------------- 16 | void testcase(void * a) 17 | { 18 | func1_count = func2_count = 0; 19 | 20 | THREAD_INIT(thread0, "thread0", func1, NULL, 5); 21 | THREAD_INIT(thread1, "thread1", func2, NULL, 5); 22 | 23 | // Background loop 24 | thread_sleep(25); 25 | assert(func1_count && func2_count); 26 | exit(0); 27 | } 28 | 29 | //----------------------------------------------------------------- 30 | // func1: 31 | //----------------------------------------------------------------- 32 | static void* func1(void* a) 33 | { 34 | int x; 35 | int i; 36 | 37 | while (1) 38 | { 39 | volatile int var = 0x1234; 40 | volatile unsigned int uvar = 0; 41 | volatile unsigned long longvar = 0; 42 | 43 | printf("\nTest:\n"); 44 | 45 | printf("1. Initialised data\n"); 46 | assert(var == 0x1234); // .text 47 | assert(uvar == 0x0); // .bss 48 | 49 | printf("2. Multiply\n"); 50 | var = var * 3; 51 | assert(var == 13980); 52 | var = -1; 53 | var = var * 3; 54 | assert(var == -3); 55 | var = -5; 56 | var = var * 13; 57 | assert(var == -65); 58 | var = -5; 59 | var = var * -13; 60 | assert(var == (-5*-13)); 61 | var = -123123415; 62 | var = var * 9664563; 63 | assert(var == (-123123415*9664563)); 64 | 65 | printf("3. Divide\n"); 66 | var = 13980; 67 | var = var / 5; 68 | assert(var == 2796); 69 | var = var % 100; 70 | assert(var == 96); 71 | var = -1273; 72 | var = var / 19; 73 | assert(var == -67); 74 | 75 | printf("4. Shift left\n"); 76 | var = 0x1; 77 | var <<= 31; 78 | assert(var == 0x80000000); 79 | 80 | printf("5. Shift right\n"); 81 | uvar = 0x80000000; 82 | uvar >>= 1; 83 | assert(uvar == 0x40000000); 84 | uvar >>= 30; 85 | assert(uvar == 0x00000001); 86 | 87 | printf("6. Shift right arithmetic\n"); 88 | var = 0x80000000; 89 | var >>= 1; 90 | assert(var == 0xC0000000); 91 | 92 | printf("7. Signed comparision\n"); 93 | var = -1; 94 | assert(var < 1); 95 | x = 10; 96 | assert(var < x); 97 | assert(!(var > x)); 98 | x = -3; 99 | assert(var > x); 100 | assert(x <= var); 101 | 102 | printf("8. Comparision\n"); 103 | longvar = 0x1db9; 104 | if (longvar >= 0xFFF8 && longvar <= 0xFFFF) 105 | { 106 | printf("- Incorrect comparision\n"); 107 | assert(0); 108 | } 109 | 110 | func1_count += 1; 111 | } 112 | 113 | // Success 114 | return 0; 115 | } 116 | //----------------------------------------------------------------- 117 | // func2: 118 | //----------------------------------------------------------------- 119 | static void* func2(void *a) 120 | { 121 | while (1) 122 | { 123 | volatile unsigned int a = 28; 124 | volatile int b = 65521; 125 | volatile int c = -80; 126 | volatile unsigned char d = 67; 127 | c = b >= d; 128 | b = c ^ d; 129 | b = d > c; 130 | assert(b == 1); 131 | b = -7076; 132 | assert(c == 1); 133 | d = b > d; 134 | b = -25699; 135 | d = c >> a; 136 | a = b <= d; 137 | d = 115; 138 | assert(c == 1); 139 | a = c & c; 140 | d = c | d; 141 | c = b != c; 142 | c = b <= a; 143 | c = c - b; 144 | assert(a == 1); 145 | d = d != c; 146 | assert(a == 1); 147 | d = c & d; 148 | assert(c == 25699); 149 | c = 20; 150 | d = a >> c; 151 | d = a * c; 152 | d = 26; 153 | a = c & a; 154 | d = c + c; 155 | c = c != c; 156 | b = d + a; 157 | d = a <= a; 158 | d = d << a; 159 | b = a == c; 160 | a = c * a; 161 | c = 339; 162 | assert(d == 1); 163 | a = c == d; 164 | b = c < b; 165 | b = b ^ c; 166 | b = b > d; 167 | c = a == c; 168 | assert(c == 0); 169 | assert(c == 0); 170 | c = c != c; 171 | b = c <= a; 172 | b = a != c; 173 | d = c != b; 174 | c = b - c; 175 | b = b ^ a; 176 | assert(b == 0); 177 | d = 224; 178 | d = a | d; 179 | a = c != d; 180 | b = -126402; 181 | d = c * a; 182 | assert(d == 0); 183 | a = d - b; 184 | assert(a == 126402); 185 | a = c == c; 186 | d = b + a; 187 | assert(c == 0); 188 | b = 39462; 189 | c = d != c; 190 | c = a + c; 191 | b = -41083; 192 | assert(d == 63); 193 | b = b >= c; 194 | b = a < a; 195 | c = a == b; 196 | d = 27; 197 | b = a >> d; 198 | b = -18660; 199 | assert(c == 0); 200 | a = 3; 201 | a = c + a; 202 | b = 19; 203 | b = c >> b; 204 | assert(d == 27); 205 | b = d == b; 206 | assert(b == 0); 207 | b = c != a; 208 | a = a <= d; 209 | a = a & b; 210 | a = d < d; 211 | b = c >> d; 212 | a = 7; 213 | assert(d == 27); 214 | d = d < a; 215 | b = d & d; 216 | c = d - a; 217 | d = a + a; 218 | a = d < b; 219 | a = c ^ d; 220 | a = 26; 221 | assert(b == 0); 222 | assert(a == 26); 223 | b = d & b; 224 | d = d + c; 225 | a = c - b; 226 | d = d != b; 227 | d = a * c; 228 | b = d + a; 229 | b = 44080; 230 | a = d | b; 231 | b = a < b; 232 | a = c * c; 233 | d = 126; 234 | d = c | b; 235 | b = a | c; 236 | d = 234; 237 | d = c ^ d; 238 | d = a << d; 239 | b = d + a; 240 | assert(c == -7); 241 | c = c * a; 242 | b = -20292; 243 | b = a & b; 244 | d = d * b; 245 | a = 22; 246 | d = c << a; 247 | b = -107052; 248 | a = b == a; 249 | a = d - d; 250 | a = 31; 251 | a = a + b; 252 | c = d * a; 253 | assert(d == 0); 254 | assert(c == 0); 255 | assert(d == 0); 256 | assert(b == -107052); 257 | d = d > b; 258 | d = b - b; 259 | a = a - a; 260 | b = c < c; 261 | b = c << a; 262 | d = a << b; 263 | b = a >> b; 264 | b = 75097; 265 | b = b << d; 266 | b = d >> a; 267 | b = 30159; 268 | a = b | d; 269 | c = a >> c; 270 | d = a >= d; 271 | d = a + d; 272 | b = c != c; 273 | c = 409; 274 | c = a >= d; 275 | assert(c == 1); 276 | a = b ^ b; 277 | c = c << c; 278 | b = d >= d; 279 | b = -30117; 280 | c = a == c; 281 | b = -46167; 282 | c = -448; 283 | assert(b == -46167); 284 | assert(b == -46167); 285 | c = c + c; 286 | assert(b == -46167); 287 | c = -212; 288 | a = b < b; 289 | b = 22; 290 | b = d << b; 291 | d = 25; 292 | c = a << d; 293 | b = d <= b; 294 | a = d - c; 295 | b = a <= a; 296 | a = c | a; 297 | c = c >= c; 298 | d = b | b; 299 | assert(c == 1); 300 | b = -72284; 301 | b = a + a; 302 | a = 32; 303 | b = d == b; 304 | a = d == d; 305 | b = b + a; 306 | b = a <= c; 307 | a = c >= c; 308 | b = -115697; 309 | b = -114943; 310 | d = d * b; 311 | a = a << d; 312 | c = 330; 313 | a = a * b; 314 | b = 18; 315 | d = d << b; 316 | b = c >= a; 317 | b = c > c; 318 | a = a * d; 319 | c = 160; 320 | c = c * d; 321 | c = a == c; 322 | c = c <= c; 323 | a = 8; 324 | d = 142; 325 | b = c * a; 326 | b = d - c; 327 | d = d & d; 328 | d = 194; 329 | assert(b == 141); 330 | a = d == c; 331 | a = 22; 332 | b = d >= b; 333 | b = 81711; 334 | d = b + a; 335 | b = 23; 336 | c = d << b; 337 | c = b >= c; 338 | b = c < c; 339 | a = c + a; 340 | a = c - a; 341 | d = b <= d; 342 | b = b == a; 343 | d = c << b; 344 | c = c >> c; 345 | d = b + b; 346 | c = -352; 347 | b = d > d; 348 | d = 175; 349 | a = a | d; 350 | c = b | a; 351 | b = d + c; 352 | d = a >= a; 353 | c = -95; 354 | b = b >= b; 355 | d = 146; 356 | b = -24440; 357 | b = a + c; 358 | c = c >= d; 359 | c = a == c; 360 | d = d & a; 361 | b = d & d; 362 | assert(c == 0); 363 | d = b + c; 364 | d = c == d; 365 | c = b | d; 366 | d = a + a; 367 | d = 30; 368 | a = d >> d; 369 | d = d <= c; 370 | c = b < d; 371 | a = c * a; 372 | c = -234; 373 | b = 113349; 374 | c = c <= d; 375 | c = -345; 376 | c = d == c; 377 | d = c | b; 378 | d = a ^ a; 379 | d = c | c; 380 | assert(b == 113349); 381 | b = d - d; 382 | b = c ^ b; 383 | d = c < d; 384 | assert(c == 0); 385 | b = d | d; 386 | a = a > a; 387 | d = b | d; 388 | b = d >> a; 389 | a = c + b; 390 | b = c & a; 391 | b = a * a; 392 | assert(a == 0); 393 | assert(d == 0); 394 | d = b | c; 395 | b = b * a; 396 | c = -454; 397 | c = 131; 398 | d = b - c; 399 | c = d > a; 400 | assert(c == 1); 401 | d = a & d; 402 | a = c + c; 403 | a = 15; 404 | a = b == a; 405 | c = b ^ c; 406 | d = b - d; 407 | assert(a == 0); 408 | c = d * d; 409 | b = a + c; 410 | d = a - b; 411 | c = 212; 412 | b = d - a; 413 | a = 19; 414 | d = 49; 415 | b = b == a; 416 | a = c + c; 417 | d = 3; 418 | b = c >> d; 419 | assert(a == 424); 420 | assert(a == 424); 421 | b = d + b; 422 | d = c + b; 423 | b = a < c; 424 | a = d > c; 425 | d = 28; 426 | d = c >> d; 427 | c = a >= a; 428 | assert(b == 0); 429 | b = d & a; 430 | a = d != a; 431 | assert(a == 1); 432 | c = a * d; 433 | c = d != c; 434 | a = b == d; 435 | a = a ^ c; 436 | assert(d == 0); 437 | b = b <= b; 438 | b = c & b; 439 | d = d != d; 440 | a = c > b; 441 | assert(d == 0); 442 | b = -120194; 443 | assert(c == 0); 444 | c = c == a; 445 | b = c >= d; 446 | c = d | b; 447 | d = c <= d; 448 | d = a >= c; 449 | b = -58657; 450 | c = b | a; 451 | a = b - b; 452 | c = c ^ d; 453 | c = a > a; 454 | assert(b == -58657); 455 | c = c * b; 456 | assert(a == 0); 457 | d = b == c; 458 | c = -195; 459 | assert(c == -195); 460 | d = 175; 461 | b = 110627; 462 | c = c <= c; 463 | b = 29034; 464 | assert(b == 29034); 465 | d = b << a; 466 | assert(c == 1); 467 | assert(a == 0); 468 | assert(a == 0); 469 | d = c <= c; 470 | c = b * a; 471 | assert(c == 0); 472 | d = a == c; 473 | c = b * b; 474 | c = 6; 475 | d = b >> c; 476 | assert(a == 0); 477 | a = a != a; 478 | d = c > b; 479 | a = a < d; 480 | d = d & a; 481 | c = -10; 482 | assert(b == 29034); 483 | b = a <= a; 484 | d = b >> a; 485 | c = b & a; 486 | c = -269; 487 | assert(b == 1); 488 | d = 103; 489 | c = b != c; 490 | d = b != b; 491 | d = d >> d; 492 | b = b <= a; 493 | d = b != a; 494 | assert(d == 0); 495 | c = c ^ c; 496 | b = b * c; 497 | assert(d == 0); 498 | d = c * a; 499 | d = 93; 500 | a = a + b; 501 | a = c <= d; 502 | assert(b == 0); 503 | d = a > a; 504 | d = b << d; 505 | d = c & b; 506 | a = 20; 507 | a = d >= c; 508 | c = c != c; 509 | c = c ^ a; 510 | a = a * d; 511 | d = b == b; 512 | b = b == c; 513 | d = a >> a; 514 | a = c != a; 515 | d = b > b; 516 | a = 20; 517 | d = d - c; 518 | assert(c == 1); 519 | d = 196; 520 | b = c <= b; 521 | assert(d == 196); 522 | b = -80467; 523 | d = c << c; 524 | c = d <= c; 525 | assert(a == 20); 526 | c = a * a; 527 | b = 91936; 528 | assert(d == 2); 529 | d = b < c; 530 | b = 21; 531 | c = b << b; 532 | c = 252; 533 | d = b ^ b; 534 | d = c <= a; 535 | d = c << d; 536 | a = 16; 537 | assert(d == 252); 538 | c = -188; 539 | assert(d == 252); 540 | a = d < c; 541 | assert(a == 0); 542 | a = b == c; 543 | d = b < a; 544 | assert(d == 0); 545 | b = b + c; 546 | c = 386; 547 | a = b > a; 548 | d = 49; 549 | d = c & b; 550 | assert(a == 1); 551 | b = b | d; 552 | b = d & a; 553 | c = 17; 554 | c = d >> c; 555 | b = 125872; 556 | c = d | b; 557 | assert(d == 0); 558 | b = d <= d; 559 | a = 25; 560 | b = 114336; 561 | a = c * b; 562 | c = d == c; 563 | b = b << c; 564 | d = d > a; 565 | assert(a == 1506799104); 566 | a = 11; 567 | b = 88751; 568 | d = 107; 569 | d = 125; 570 | b = a ^ b; 571 | a = d > b; 572 | assert(d == 125); 573 | a = d * c; 574 | b = 30; 575 | a = b >> b; 576 | a = c == d; 577 | a = a < b; 578 | c = b > a; 579 | assert(c == 1); 580 | a = c & d; 581 | a = a >= d; 582 | b = 73656; 583 | d = a ^ a; 584 | a = c * b; 585 | a = a - d; 586 | d = d << c; 587 | b = 99702; 588 | a = a + a; 589 | a = 14; 590 | d = c << a; 591 | d = d | a; 592 | a = 12; 593 | d = c * c; 594 | b = c <= d; 595 | b = b >> b; 596 | a = 13; 597 | a = 25; 598 | d = a ^ a; 599 | assert(b == 0); 600 | d = c >> d; 601 | b = b - c; 602 | c = d - b; 603 | d = 1; 604 | d = d < a; 605 | d = b + d; 606 | assert(c == 2); 607 | d = b != d; 608 | b = b & b; 609 | d = c + d; 610 | assert(c == 2); 611 | a = 20; 612 | assert(a == 20); 613 | d = a + d; 614 | c = d << c; 615 | b = -40862; 616 | a = d >= c; 617 | assert(b == -40862); 618 | a = d * a; 619 | c = 5; 620 | b = c << c; 621 | d = 198; 622 | c = -18; 623 | c = a > d; 624 | d = c ^ c; 625 | d = 36; 626 | assert(b == 160); 627 | b = d != a; 628 | c = d << a; 629 | a = c & b; 630 | assert(d == 36); 631 | assert(b == 1); 632 | a = d <= a; 633 | d = d >= c; 634 | b = b | a; 635 | a = d + a; 636 | b = d ^ d; 637 | c = -177; 638 | a = c != a; 639 | b = b ^ b; 640 | a = b != b; 641 | b = b <= a; 642 | c = d < c; 643 | a = a & b; 644 | c = c == c; 645 | d = 190; 646 | d = 10; 647 | b = d ^ b; 648 | a = a << a; 649 | c = c + a; 650 | b = d > a; 651 | b = d + d; 652 | c = 388; 653 | c = d < d; 654 | assert(d == 10); 655 | assert(b == 20); 656 | assert(d == 10); 657 | c = d << a; 658 | d = c | d; 659 | c = b >= b; 660 | assert(b == 20); 661 | d = d == a; 662 | c = 50; 663 | assert(c == 50); 664 | b = c | c; 665 | c = a <= b; 666 | b = c != b; 667 | c = a | d; 668 | a = c ^ a; 669 | a = 30; 670 | d = b * d; 671 | a = d | d; 672 | assert(a == 0); 673 | b = 125859; 674 | assert(a == 0); 675 | c = b | c; 676 | d = 211; 677 | c = a != c; 678 | assert(c == 1); 679 | c = d >= a; 680 | d = c * a; 681 | c = -229; 682 | assert(d == 0); 683 | a = d ^ a; 684 | b = a > d; 685 | assert(b == 0); 686 | d = c < a; 687 | a = c * a; 688 | b = a <= b; 689 | a = b > d; 690 | c = c <= c; 691 | assert(d == 0); 692 | a = c != a; 693 | assert(a == 0); 694 | c = d << b; 695 | c = d - a; 696 | b = b == c; 697 | d = c * b; 698 | c = c + a; 699 | c = c << c; 700 | b = a * c; 701 | c = c <= a; 702 | assert(b == 0); 703 | c = c - a; 704 | d = a <= a; 705 | c = c != b; 706 | a = 20; 707 | a = b <= d; 708 | c = d ^ b; 709 | a = a >> a; 710 | b = 41728; 711 | c = d * a; 712 | b = c > c; 713 | a = d + a; 714 | c = -355; 715 | c = b == c; 716 | d = a ^ d; 717 | b = c + b; 718 | b = b ^ c; 719 | d = b < a; 720 | assert(c == 0); 721 | assert(c == 0); 722 | d = b - b; 723 | b = d > a; 724 | a = d & c; 725 | b = 74422; 726 | a = c & c; 727 | a = 21; 728 | c = -356; 729 | assert(a == 21); 730 | c = a > b; 731 | assert(d == 0); 732 | c = a - d; 733 | b = c + b; 734 | b = a | d; 735 | a = d == a; 736 | d = d ^ b; 737 | a = 32; 738 | d = b | b; 739 | a = c >= d; 740 | a = 2; 741 | d = b << c; 742 | c = c + a; 743 | a = b >> b; 744 | assert(c == 23); 745 | b = 91631; 746 | a = a | b; 747 | d = b * d; 748 | assert(c == 23); 749 | assert(a == 91631); 750 | b = c & d; 751 | b = a ^ d; 752 | a = 4; 753 | a = d >= c; 754 | c = c + c; 755 | a = a << d; 756 | b = c & b; 757 | d = b * a; 758 | d = 227; 759 | a = c > c; 760 | d = c < b; 761 | b = 18019; 762 | c = a >= a; 763 | c = b != b; 764 | b = c != c; 765 | assert(d == 0); 766 | c = b >> c; 767 | c = d > c; 768 | assert(b == 0); 769 | d = 180; 770 | c = 319; 771 | a = d | d; 772 | c = a >> b; 773 | b = a - c; 774 | b = 112013; 775 | b = b + a; 776 | b = c + c; 777 | c = -81; 778 | c = c + a; 779 | a = 25; 780 | d = b & d; 781 | c = c < c; 782 | b = 120394; 783 | d = d | c; 784 | assert(c == 0); 785 | c = a << a; 786 | a = a != b; 787 | d = 3; 788 | c = a >> d; 789 | a = 6; 790 | c = d << d; 791 | b = b + d; 792 | b = d * a; 793 | d = b >= d; 794 | a = d >> b; 795 | assert(c == 24); 796 | assert(b == 18); 797 | b = a != d; 798 | b = a + a; 799 | d = d - b; 800 | d = 20; 801 | assert(a == 0); 802 | b = -13796; 803 | c = d < c; 804 | b = d - c; 805 | c = a > d; 806 | c = d ^ d; 807 | assert(b == 19); 808 | a = c != a; 809 | d = b == b; 810 | c = 193; 811 | c = a >> a; 812 | assert(b == 19); 813 | a = c == d; 814 | d = a < d; 815 | a = 8; 816 | d = 253; 817 | c = a != b; 818 | d = 235; 819 | assert(d == 235); 820 | c = a <= c; 821 | b = -62638; 822 | d = d < c; 823 | a = c != c; 824 | d = c + b; 825 | c = b > d; 826 | a = 25; 827 | d = b << c; 828 | c = -484; 829 | b = 59387; 830 | c = d | c; 831 | assert(b == 59387); 832 | a = c != b; 833 | assert(a == 1); 834 | c = c - a; 835 | assert(c == -419); 836 | c = a < a; 837 | b = d ^ b; 838 | b = b >= b; 839 | b = b + c; 840 | d = c << c; 841 | d = c << d; 842 | d = c >> a; 843 | d = b << b; 844 | c = b & a; 845 | a = b - b; 846 | a = d * b; 847 | b = -87749; 848 | b = 56739; 849 | d = d ^ b; 850 | b = c * d; 851 | assert(c == 1); 852 | a = a & b; 853 | a = c & c; 854 | a = b >> a; 855 | b = d * c; 856 | c = 157; 857 | a = 9; 858 | b = b << a; 859 | b = c < d; 860 | d = d <= c; 861 | a = a >= b; 862 | assert(d == 0); 863 | c = d * b; 864 | c = b - b; 865 | b = -97375; 866 | assert(a == 1); 867 | a = 6; 868 | b = 100427; 869 | d = a - b; 870 | b = c - c; 871 | a = c | d; 872 | a = a <= c; 873 | assert(b == 0); 874 | c = c | d; 875 | c = b < d; 876 | a = c ^ a; 877 | assert(b == 0); 878 | d = 255; 879 | b = a >> b; 880 | a = d * b; 881 | d = a > a; 882 | c = c & d; 883 | a = 9; 884 | b = c < c; 885 | a = c >= d; 886 | a = a ^ c; 887 | assert(b == 0); 888 | b = d == a; 889 | b = c + c; 890 | c = d & a; 891 | a = a - d; 892 | a = 25; 893 | c = d != b; 894 | c = c != c; 895 | c = 69; 896 | d = 17; 897 | c = d >= d; 898 | b = b == d; 899 | assert(b == 0); 900 | b = c == b; 901 | b = -72630; 902 | b = 23; 903 | d = b << b; 904 | assert(d == 0); 905 | assert(c == 1); 906 | assert(a == 25); 907 | a = d * c; 908 | assert(a == 0); 909 | a = a - c; 910 | c = a < d; 911 | c = c * b; 912 | b = b <= d; 913 | a = c >= b; 914 | assert(b == 0); 915 | d = a > d; 916 | b = 11745; 917 | d = b == a; 918 | d = d & d; 919 | b = b > b; 920 | assert(d == 0); 921 | d = 160; 922 | d = c == d; 923 | d = 209; 924 | b = b + b; 925 | assert(a == 1); 926 | b = c << b; 927 | assert(a == 1); 928 | d = d << a; 929 | a = 5; 930 | assert(c == 0); 931 | b = c * d; 932 | assert(d == 162); 933 | c = a != d; 934 | b = c ^ b; 935 | d = 27; 936 | d = a << d; 937 | d = c ^ b; 938 | assert(a == 5); 939 | b = d >= c; 940 | d = 242; 941 | b = b > b; 942 | d = d + d; 943 | assert(c == 1); 944 | b = a ^ c; 945 | b = 74713; 946 | d = d | a; 947 | c = d > b; 948 | c = b - a; 949 | a = b ^ c; 950 | c = d != a; 951 | c = d | d; 952 | c = d & d; 953 | assert(d == 229); 954 | d = b & a; 955 | b = c | d; 956 | d = a << a; 957 | d = a ^ c; 958 | c = a - a; 959 | a = 4; 960 | d = b < d; 961 | b = c ^ c; 962 | a = 14; 963 | c = c <= d; 964 | b = a + a; 965 | a = d >= b; 966 | a = c - b; 967 | assert(d == 0); 968 | d = 105; 969 | b = c | b; 970 | d = d ^ c; 971 | c = 40; 972 | a = a * a; 973 | d = 140; 974 | b = d + b; 975 | d = 220; 976 | d = d <= c; 977 | c = c != b; 978 | b = d == c; 979 | assert(a == 729); 980 | a = b > c; 981 | a = d + d; 982 | c = a * b; 983 | d = a - b; 984 | d = c & b; 985 | assert(a == 0); 986 | c = b >= b; 987 | b = -107268; 988 | d = b == b; 989 | d = a >> d; 990 | c = a != d; 991 | b = d < b; 992 | a = c | a; 993 | a = a >= b; 994 | assert(d == 0); 995 | d = d != c; 996 | d = 42; 997 | c = d < c; 998 | b = c < b; 999 | c = d < d; 1000 | c = a ^ a; 1001 | assert(b == 0); 1002 | d = a ^ c; 1003 | assert(b == 0); 1004 | a = a > d; 1005 | c = a == c; 1006 | d = 115; 1007 | b = 124002; 1008 | b = b == b; 1009 | a = b == b; 1010 | assert(d == 115); 1011 | c = b + d; 1012 | d = a < a; 1013 | d = a >= d; 1014 | a = c & a; 1015 | d = c | b; 1016 | c = a | b; 1017 | b = a + d; 1018 | assert(c == 1); 1019 | assert(b == 117); 1020 | c = 36; 1021 | assert(c == 36); 1022 | c = d * a; 1023 | a = a + a; 1024 | c = c | c; 1025 | b = b | a; 1026 | b = -73474; 1027 | c = c | c; 1028 | assert(c == 0); 1029 | assert(a == 0); 1030 | c = d ^ d; 1031 | b = a >= c; 1032 | c = 310; 1033 | d = d & b; 1034 | assert(c == 310); 1035 | a = b ^ b; 1036 | assert(a == 0); 1037 | assert(c == 310); 1038 | b = b == b; 1039 | d = c | c; 1040 | b = b != a; 1041 | b = 63117; 1042 | d = 15; 1043 | a = a >> d; 1044 | a = c - a; 1045 | b = d - b; 1046 | b = 17; 1047 | c = a >> b; 1048 | b = d | d; 1049 | d = 212; 1050 | a = d > b; 1051 | a = a > b; 1052 | d = a != b; 1053 | a = 15; 1054 | b = 60439; 1055 | c = b + a; 1056 | b = c >= d; 1057 | a = b == b; 1058 | b = 45282; 1059 | b = a <= d; 1060 | c = 473; 1061 | a = c ^ c; 1062 | b = b == a; 1063 | c = d | c; 1064 | c = 447; 1065 | a = d & b; 1066 | assert(c == 447); 1067 | a = a != c; 1068 | c = -263; 1069 | d = b == d; 1070 | d = c - b; 1071 | d = 55; 1072 | c = c ^ d; 1073 | d = b | c; 1074 | a = a > b; 1075 | a = b < a; 1076 | d = a - b; 1077 | assert(a == 1); 1078 | b = a >> a; 1079 | c = c + a; 1080 | a = b & d; 1081 | d = d >= d; 1082 | c = b | d; 1083 | b = d >> d; 1084 | b = b < b; 1085 | d = a < c; 1086 | d = a + a; 1087 | assert(b == 0); 1088 | c = a + c; 1089 | assert(a == 0); 1090 | c = d + a; 1091 | d = c > a; 1092 | c = 402; 1093 | assert(d == 0); 1094 | b = d >> d; 1095 | assert(a == 0); 1096 | b = d >> b; 1097 | d = 242; 1098 | c = b + d; 1099 | d = c >= a; 1100 | d = a < b; 1101 | assert(b == 0); 1102 | assert(d == 0); 1103 | b = b >= a; 1104 | d = b == b; 1105 | c = c * b; 1106 | c = c == a; 1107 | a = 26; 1108 | a = b | c; 1109 | assert(b == 1); 1110 | d = a != a; 1111 | b = a ^ d; 1112 | d = d != d; 1113 | d = c & a; 1114 | a = c + b; 1115 | d = d <= c; 1116 | b = c <= a; 1117 | a = d < d; 1118 | a = c <= d; 1119 | d = b + d; 1120 | assert(d == 2); 1121 | assert(b == 1); 1122 | d = d >> c; 1123 | a = d << a; 1124 | a = b >= a; 1125 | d = 17; 1126 | b = a * b; 1127 | a = c >> a; 1128 | b = a * c; 1129 | a = b <= b; 1130 | d = 171; 1131 | c = d << b; 1132 | d = 156; 1133 | b = d >= b; 1134 | d = d <= a; 1135 | c = a << d; 1136 | a = d + c; 1137 | a = b << c; 1138 | d = 12; 1139 | a = 22; 1140 | c = c | a; 1141 | c = d + d; 1142 | c = b * b; 1143 | a = a >> a; 1144 | b = a >> c; 1145 | a = b >> d; 1146 | assert(b == 0); 1147 | b = b & d; 1148 | b = 61364; 1149 | d = a & b; 1150 | c = c == d; 1151 | c = c >= d; 1152 | assert(d == 0); 1153 | b = d >= b; 1154 | assert(a == 0); 1155 | d = b > a; 1156 | d = 222; 1157 | assert(a == 0); 1158 | assert(d == 222); 1159 | c = d > d; 1160 | d = 107; 1161 | b = b + c; 1162 | d = c + c; 1163 | a = a & c; 1164 | a = d < b; 1165 | a = 9; 1166 | b = -14784; 1167 | d = 248; 1168 | c = a + c; 1169 | b = a + d; 1170 | c = b > c; 1171 | b = 26; 1172 | b = b >> b; 1173 | c = d ^ c; 1174 | c = c & c; 1175 | b = b - c; 1176 | assert(b == -249); 1177 | d = c <= d; 1178 | b = 6; 1179 | b = a << b; 1180 | c = 410; 1181 | d = d | a; 1182 | c = a & a; 1183 | d = d >> d; 1184 | c = b != b; 1185 | assert(a == 9); 1186 | a = a <= b; 1187 | b = b ^ b; 1188 | c = c - d; 1189 | c = c & d; 1190 | c = b * a; 1191 | b = c <= b; 1192 | d = d >= b; 1193 | a = d & c; 1194 | a = 22; 1195 | b = 1788; 1196 | assert(c == 0); 1197 | b = -54740; 1198 | a = a <= b; 1199 | b = -124375; 1200 | assert(b == -124375); 1201 | b = b < b; 1202 | a = a != a; 1203 | d = b ^ d; 1204 | d = 201; 1205 | a = a > a; 1206 | a = a | b; 1207 | assert(b == 0); 1208 | c = c != b; 1209 | a = 12; 1210 | a = 28; 1211 | b = c - d; 1212 | c = b <= a; 1213 | b = 5; 1214 | d = c >> b; 1215 | d = c << a; 1216 | c = 112; 1217 | d = 14; 1218 | a = 30; 1219 | c = c >> b; 1220 | c = b - b; 1221 | b = d >> d; 1222 | a = c - d; 1223 | a = 10; 1224 | a = c & d; 1225 | d = c >> c; 1226 | assert(b == 0); 1227 | b = b + c; 1228 | a = d - c; 1229 | assert(c == 0); 1230 | a = c > a; 1231 | assert(b == 0); 1232 | a = 2; 1233 | b = b - c; 1234 | c = a > a; 1235 | d = d + b; 1236 | b = d - c; 1237 | assert(d == 0); 1238 | d = c | d; 1239 | a = c > b; 1240 | assert(b == 0); 1241 | assert(d == 0); 1242 | a = d - a; 1243 | a = 19; 1244 | c = b - d; 1245 | a = a * d; 1246 | c = d * d; 1247 | b = a << d; 1248 | a = 4; 1249 | d = 234; 1250 | d = 72; 1251 | d = a <= b; 1252 | b = c < a; 1253 | assert(d == 0); 1254 | c = d == a; 1255 | b = c ^ d; 1256 | d = d == d; 1257 | b = 25970; 1258 | d = d << d; 1259 | c = b > b; 1260 | d = b != b; 1261 | a = 26; 1262 | a = b <= a; 1263 | b = d - b; 1264 | d = d - c; 1265 | a = b >= b; 1266 | d = d < b; 1267 | b = 31; 1268 | b = a << b; 1269 | b = 49832; 1270 | b = a >= c; 1271 | c = a | b; 1272 | c = c >> a; 1273 | d = 153; 1274 | assert(a == 1); 1275 | a = c << b; 1276 | a = 16; 1277 | c = c + a; 1278 | b = c ^ d; 1279 | c = d * a; 1280 | b = c != b; 1281 | assert(c == 2448); 1282 | c = b <= a; 1283 | assert(b == 1); 1284 | d = 87; 1285 | c = c < a; 1286 | c = c >> a; 1287 | b = d + d; 1288 | d = c > b; 1289 | assert(d == 0); 1290 | d = 137; 1291 | assert(c == 0); 1292 | d = b | a; 1293 | a = 28; 1294 | d = b << a; 1295 | d = 194; 1296 | c = a != d; 1297 | d = 19; 1298 | a = a << d; 1299 | c = 144; 1300 | b = a >= a; 1301 | a = d > a; 1302 | c = d >= c; 1303 | d = a >> c; 1304 | assert(a == 0); 1305 | assert(d == 0); 1306 | c = d >= d; 1307 | a = b >= d; 1308 | b = d << a; 1309 | b = d - b; 1310 | d = d - b; 1311 | b = c - b; 1312 | a = 10; 1313 | b = b >> c; 1314 | c = d + b; 1315 | assert(b == 0); 1316 | d = b << c; 1317 | a = b <= d; 1318 | c = a != a; 1319 | c = b << b; 1320 | assert(d == 0); 1321 | c = b | b; 1322 | c = c > b; 1323 | assert(d == 0); 1324 | assert(c == 0); 1325 | c = a <= d; 1326 | a = c != a; 1327 | assert(b == 0); 1328 | a = d + b; 1329 | b = d >> b; 1330 | c = b * d; 1331 | c = d ^ b; 1332 | assert(a == 0); 1333 | d = c ^ d; 1334 | c = d * a; 1335 | a = d ^ a; 1336 | assert(b == 0); 1337 | a = c & c; 1338 | b = d << c; 1339 | assert(d == 0); 1340 | a = 16; 1341 | a = c & c; 1342 | c = b * d; 1343 | d = a >> d; 1344 | assert(a == 0); 1345 | d = d < c; 1346 | b = -85932; 1347 | a = d == b; 1348 | d = 124; 1349 | assert(d == 124); 1350 | c = c + d; 1351 | assert(c == 124); 1352 | c = b * d; 1353 | c = 291; 1354 | c = a <= d; 1355 | d = c ^ d; 1356 | a = d << c; 1357 | b = 6; 1358 | c = d << b; 1359 | assert(a == 250); 1360 | c = 187; 1361 | d = a < d; 1362 | c = 176; 1363 | a = a * c; 1364 | c = c + c; 1365 | d = b ^ b; 1366 | assert(a == 44000); 1367 | c = a * b; 1368 | assert(c == 264000); 1369 | a = a != c; 1370 | b = c + c; 1371 | a = a <= a; 1372 | d = a & a; 1373 | b = -108005; 1374 | b = b + c; 1375 | c = 22; 1376 | a = a << c; 1377 | assert(c == 22); 1378 | b = -56748; 1379 | a = b > c; 1380 | d = b * c; 1381 | a = d * c; 1382 | d = 15; 1383 | b = c << d; 1384 | d = c & d; 1385 | c = d <= d; 1386 | c = c >= b; 1387 | assert(c == 0); 1388 | assert(b == 720896); 1389 | assert(a == 1232); 1390 | d = 129; 1391 | assert(a == 1232); 1392 | b = d < b; 1393 | assert(c == 0); 1394 | b = 11313; 1395 | d = d <= d; 1396 | a = 19; 1397 | b = c << a; 1398 | d = a >= b; 1399 | a = b >> d; 1400 | d = d | d; 1401 | b = d < c; 1402 | c = b <= c; 1403 | b = -37847; 1404 | c = a >> a; 1405 | a = a >= d; 1406 | a = a <= a; 1407 | assert(c == 0); 1408 | b = d + c; 1409 | c = -96; 1410 | assert(a == 1); 1411 | a = a + a; 1412 | assert(a == 2); 1413 | assert(a == 2); 1414 | c = 428; 1415 | d = 76; 1416 | b = c >> a; 1417 | assert(b == 107); 1418 | c = a ^ b; 1419 | d = b * b; 1420 | b = 82108; 1421 | assert(c == 105); 1422 | assert(c == 105); 1423 | b = d == b; 1424 | c = c & b; 1425 | a = d - a; 1426 | d = 30; 1427 | c = d << d; 1428 | c = a >> b; 1429 | assert(b == 0); 1430 | b = b <= c; 1431 | c = b > a; 1432 | c = c != b; 1433 | d = b >> c; 1434 | a = b << d; 1435 | b = -117822; 1436 | a = b >> a; 1437 | b = b ^ a; 1438 | assert(b == 76323); 1439 | assert(a == 4294908385); 1440 | c = d > c; 1441 | assert(c == 0); 1442 | c = d & a; 1443 | assert(c == 0); 1444 | assert(c == 0); 1445 | assert(a == 4294908385); 1446 | a = 4; 1447 | a = a ^ a; 1448 | b = b * b; 1449 | c = -111; 1450 | a = 23; 1451 | b = b | a; 1452 | b = c >> a; 1453 | b = c + a; 1454 | b = a >= d; 1455 | d = c * d; 1456 | assert(c == -111); 1457 | assert(a == 23); 1458 | c = 313; 1459 | assert(a == 23); 1460 | a = 11; 1461 | c = d - b; 1462 | a = 9; 1463 | a = d == a; 1464 | c = d & d; 1465 | d = c >> a; 1466 | b = b & d; 1467 | c = 292; 1468 | c = c * b; 1469 | a = d < b; 1470 | b = c + b; 1471 | d = 79; 1472 | d = c >= b; 1473 | assert(c == 0); 1474 | c = c * d; 1475 | c = c & a; 1476 | d = a * a; 1477 | b = b >> d; 1478 | a = c << d; 1479 | assert(a == 0); 1480 | d = c >= d; 1481 | d = 213; 1482 | c = d <= d; 1483 | d = 209; 1484 | b = 56901; 1485 | assert(b == 56901); 1486 | b = d <= c; 1487 | a = 5; 1488 | a = a >> c; 1489 | a = 28; 1490 | assert(d == 209); 1491 | b = b & d; 1492 | a = d != b; 1493 | assert(b == 0); 1494 | assert(d == 209); 1495 | c = 426; 1496 | d = d & a; 1497 | d = c < a; 1498 | b = c != b; 1499 | a = c ^ b; 1500 | b = 76696; 1501 | a = b < b; 1502 | c = -407; 1503 | b = b << d; 1504 | assert(b == 76696); 1505 | assert(b == 76696); 1506 | d = 67; 1507 | b = c + b; 1508 | c = 10; 1509 | b = c << c; 1510 | d = 4; 1511 | c = d >> d; 1512 | c = a | a; 1513 | a = c << c; 1514 | c = 393; 1515 | a = c <= a; 1516 | c = b & a; 1517 | d = c >= a; 1518 | a = 17; 1519 | assert(a == 17); 1520 | d = b <= b; 1521 | c = c > a; 1522 | assert(b == 10240); 1523 | c = d ^ d; 1524 | b = b & a; 1525 | b = a <= a; 1526 | assert(c == 0); 1527 | assert(b == 1); 1528 | b = b << c; 1529 | a = 19; 1530 | a = 1; 1531 | b = a << a; 1532 | c = b >= d; 1533 | d = d < b; 1534 | assert(b == 2); 1535 | d = 103; 1536 | a = 15; 1537 | assert(c == 1); 1538 | c = c | b; 1539 | c = c > c; 1540 | c = a >= b; 1541 | assert(a == 15); 1542 | d = a ^ c; 1543 | a = c != b; 1544 | assert(a == 1); 1545 | b = d | a; 1546 | c = d << b; 1547 | b = d < b; 1548 | assert(b == 1); 1549 | c = b < b; 1550 | assert(b == 1); 1551 | b = c >= a; 1552 | a = b == a; 1553 | d = c << d; 1554 | a = b * a; 1555 | c = 441; 1556 | c = a != a; 1557 | a = c >= c; 1558 | assert(c == 0); 1559 | assert(c == 0); 1560 | d = d > b; 1561 | a = d >> b; 1562 | a = d < c; 1563 | a = b < b; 1564 | a = 19; 1565 | a = 1; 1566 | assert(a == 1); 1567 | d = c >> d; 1568 | b = c * a; 1569 | assert(d == 0); 1570 | c = b >> c; 1571 | assert(d == 0); 1572 | assert(b == 0); 1573 | b = c < d; 1574 | d = d & b; 1575 | b = d > b; 1576 | b = a * a; 1577 | b = -51063; 1578 | assert(c == 0); 1579 | d = b + c; 1580 | c = d >= c; 1581 | b = 7; 1582 | c = b << b; 1583 | b = a + a; 1584 | d = 26; 1585 | c = 24; 1586 | b = d << c; 1587 | b = b >= d; 1588 | d = b < c; 1589 | b = a * c; 1590 | d = d >= b; 1591 | a = d >= c; 1592 | d = b << c; 1593 | b = c >= a; 1594 | a = a <= a; 1595 | a = c >> d; 1596 | c = c < c; 1597 | b = 20735; 1598 | a = b - d; 1599 | d = c >> c; 1600 | assert(a == 20735); 1601 | c = a < d; 1602 | assert(a == 20735); 1603 | b = c >= c; 1604 | assert(c == 0); 1605 | c = a | c; 1606 | assert(b == 1); 1607 | c = -218; 1608 | assert(a == 20735); 1609 | c = 166; 1610 | a = 3; 1611 | a = c << a; 1612 | a = 3; 1613 | assert(b == 1); 1614 | b = a >> d; 1615 | assert(c == 166); 1616 | b = a > c; 1617 | b = 101699; 1618 | a = d * b; 1619 | d = b + c; 1620 | a = c * a; 1621 | assert(b == 101699); 1622 | assert(c == 166); 1623 | c = a | a; 1624 | b = a >= d; 1625 | assert(b == 0); 1626 | c = b < c; 1627 | d = d <= d; 1628 | a = 28; 1629 | c = b * d; 1630 | d = c <= c; 1631 | c = 324; 1632 | b = 24983; 1633 | b = a <= d; 1634 | c = a != a; 1635 | c = -16; 1636 | assert(d == 1); 1637 | a = 3; 1638 | c = c - d; 1639 | b = b > a; 1640 | d = c > c; 1641 | d = b << d; 1642 | a = c >> a; 1643 | d = 127; 1644 | a = a - b; 1645 | d = 17; 1646 | c = c >> d; 1647 | d = d * b; 1648 | d = d - a; 1649 | d = b & a; 1650 | c = -315; 1651 | b = 84160; 1652 | a = b * a; 1653 | a = a == b; 1654 | a = a + c; 1655 | a = d + d; 1656 | b = b | c; 1657 | d = b != b; 1658 | a = 16; 1659 | assert(b == -315); 1660 | b = d & c; 1661 | assert(a == 16); 1662 | d = d & d; 1663 | a = d >= d; 1664 | c = a == d; 1665 | b = -43934; 1666 | d = a ^ c; 1667 | b = c ^ b; 1668 | assert(a == 1); 1669 | b = d == b; 1670 | a = 23; 1671 | d = d >> b; 1672 | d = c - c; 1673 | a = a + b; 1674 | c = a * b; 1675 | a = c + b; 1676 | d = c > d; 1677 | assert(b == 0); 1678 | b = 108068; 1679 | b = d <= b; 1680 | a = 3; 1681 | d = a <= a; 1682 | a = a ^ a; 1683 | d = 253; 1684 | b = d <= a; 1685 | assert(b == 0); 1686 | c = c - b; 1687 | b = d >= c; 1688 | b = 112850; 1689 | assert(d == 253); 1690 | c = d < b; 1691 | b = d >> c; 1692 | b = c < b; 1693 | d = 31; 1694 | d = d >> d; 1695 | a = c == a; 1696 | assert(c == 1); 1697 | d = d <= d; 1698 | c = b == d; 1699 | c = d * b; 1700 | assert(d == 1); 1701 | d = c ^ d; 1702 | d = b & d; 1703 | a = b <= b; 1704 | d = a & c; 1705 | c = a >> c; 1706 | d = d ^ c; 1707 | b = -47156; 1708 | b = c | b; 1709 | b = a < c; 1710 | a = d * d; 1711 | c = d | d; 1712 | c = c & b; 1713 | assert(a == 1); 1714 | d = 164; 1715 | d = 14; 1716 | b = a >> d; 1717 | assert(d == 14); 1718 | assert(a == 1); 1719 | c = c <= c; 1720 | assert(c == 1); 1721 | d = c * b; 1722 | b = -5582; 1723 | b = 17; 1724 | d = d >> b; 1725 | c = b >= d; 1726 | a = d <= a; 1727 | a = 28; 1728 | c = a + c; 1729 | b = a - b; 1730 | c = c | d; 1731 | b = 41267; 1732 | assert(c == 29); 1733 | assert(d == 0); 1734 | c = c == b; 1735 | assert(b == 41267); 1736 | assert(c == 0); 1737 | a = 1; 1738 | d = c - a; 1739 | assert(b == 41267); 1740 | d = c & d; 1741 | b = d - a; 1742 | d = 187; 1743 | assert(b == -1); 1744 | a = a << c; 1745 | b = c << c; 1746 | b = b ^ b; 1747 | d = a < c; 1748 | assert(c == 0); 1749 | d = 254; 1750 | b = c >= c; 1751 | d = 22; 1752 | b = a >> d; 1753 | d = b != a; 1754 | assert(d == 1); 1755 | d = d << a; 1756 | assert(b == 0); 1757 | b = d == c; 1758 | d = 184; 1759 | c = c != d; 1760 | a = 24; 1761 | assert(d == 184); 1762 | d = d > b; 1763 | d = 33; 1764 | d = a & c; 1765 | assert(a == 24); 1766 | b = b != b; 1767 | c = c >> d; 1768 | assert(d == 0); 1769 | c = b == b; 1770 | b = d & b; 1771 | a = d >> b; 1772 | assert(c == 1); 1773 | assert(d == 0); 1774 | assert(b == 0); 1775 | assert(a == 0); 1776 | a = a + c; 1777 | assert(a == 1); 1778 | assert(a == 1); 1779 | assert(a == 1); 1780 | a = d > a; 1781 | assert(b == 0); 1782 | a = d | d; 1783 | assert(a == 0); 1784 | c = d * c; 1785 | c = b < c; 1786 | d = c | c; 1787 | b = c == c; 1788 | b = b + a; 1789 | d = d >= b; 1790 | c = d <= a; 1791 | a = b + d; 1792 | b = d >= c; 1793 | assert(b == 0); 1794 | d = b != c; 1795 | b = c << d; 1796 | assert(b == 2); 1797 | c = b > d; 1798 | c = d & a; 1799 | assert(b == 2); 1800 | assert(b == 2); 1801 | c = d * c; 1802 | b = c < a; 1803 | c = a * c; 1804 | b = d <= c; 1805 | c = c - a; 1806 | d = 244; 1807 | c = 195; 1808 | d = 196; 1809 | assert(a == 1); 1810 | assert(a == 1); 1811 | b = a <= c; 1812 | d = c >= c; 1813 | a = 27; 1814 | d = b - c; 1815 | d = a >= c; 1816 | d = 122; 1817 | assert(a == 27); 1818 | b = d >= b; 1819 | a = a <= c; 1820 | assert(c == 195); 1821 | a = c + b; 1822 | c = c > c; 1823 | a = 24; 1824 | b = d <= c; 1825 | d = d & d; 1826 | b = a & b; 1827 | b = a ^ c; 1828 | a = b > b; 1829 | d = a + d; 1830 | assert(d == 122); 1831 | a = b != b; 1832 | c = d > c; 1833 | c = d >= b; 1834 | c = a != c; 1835 | d = d >> b; 1836 | d = a > b; 1837 | d = 52; 1838 | b = c >= b; 1839 | assert(d == 52); 1840 | b = d <= c; 1841 | a = b != a; 1842 | a = b >> b; 1843 | c = b < a; 1844 | c = d << b; 1845 | a = d - b; 1846 | d = a + a; 1847 | c = b + a; 1848 | c = -191; 1849 | a = 25; 1850 | assert(d == 104); 1851 | assert(c == -191); 1852 | assert(c == -191); 1853 | c = a & c; 1854 | c = a + a; 1855 | d = 8; 1856 | d = d << d; 1857 | c = 179; 1858 | b = c > d; 1859 | a = 10; 1860 | c = d + c; 1861 | d = a - b; 1862 | b = -12426; 1863 | b = b <= c; 1864 | d = d ^ b; 1865 | d = d != a; 1866 | c = 143; 1867 | b = b != b; 1868 | c = b * d; 1869 | a = d ^ d; 1870 | assert(a == 0); 1871 | b = 6583; 1872 | a = 30; 1873 | a = a <= a; 1874 | a = c <= c; 1875 | b = -1703; 1876 | c = d == c; 1877 | a = b > a; 1878 | c = c != a; 1879 | b = d != a; 1880 | d = b ^ c; 1881 | d = d | b; 1882 | c = a != d; 1883 | a = 2; 1884 | a = 16; 1885 | a = c | c; 1886 | c = a >> d; 1887 | c = a > a; 1888 | c = 77; 1889 | a = b * b; 1890 | b = d < a; 1891 | assert(a == 0); 1892 | d = b >> a; 1893 | d = a & b; 1894 | c = a & b; 1895 | a = 28; 1896 | a = d <= b; 1897 | c = b * d; 1898 | c = b + c; 1899 | a = c * d; 1900 | b = a * d; 1901 | c = b != c; 1902 | a = d != a; 1903 | d = c * c; 1904 | c = 99; 1905 | assert(a == 0); 1906 | assert(a == 0); 1907 | d = 176; 1908 | b = b <= d; 1909 | c = a * d; 1910 | b = 113086; 1911 | a = b & c; 1912 | a = d < a; 1913 | a = d | a; 1914 | d = 21; 1915 | a = 11; 1916 | assert(b == 113086); 1917 | a = b | d; 1918 | b = -16395; 1919 | b = d != a; 1920 | d = d * d; 1921 | assert(d == 185); 1922 | d = d < c; 1923 | assert(d == 0); 1924 | a = a - d; 1925 | d = 231; 1926 | d = c == c; 1927 | c = c != b; 1928 | b = d + d; 1929 | d = b * d; 1930 | assert(c == 1); 1931 | c = d == b; 1932 | a = 24; 1933 | d = c <= b; 1934 | c = 355; 1935 | c = -201; 1936 | assert(c == -201); 1937 | assert(c == -201); 1938 | a = 7; 1939 | assert(c == -201); 1940 | d = b | b; 1941 | a = d << b; 1942 | d = d | c; 1943 | d = a > a; 1944 | assert(a == 8); 1945 | a = a < c; 1946 | a = 9; 1947 | c = c <= a; 1948 | a = b + b; 1949 | assert(d == 0); 1950 | assert(b == 2); 1951 | d = 171; 1952 | assert(a == 4); 1953 | b = c << b; 1954 | assert(a == 4); 1955 | assert(b == 0); 1956 | assert(d == 171); 1957 | a = b | a; 1958 | assert(c == 0); 1959 | d = 203; 1960 | b = c >= a; 1961 | b = c >= c; 1962 | b = a > c; 1963 | c = d + a; 1964 | assert(c == 207); 1965 | b = 96471; 1966 | b = a < d; 1967 | d = 38; 1968 | b = b == a; 1969 | c = a - d; 1970 | c = -53; 1971 | c = c >= a; 1972 | c = d <= b; 1973 | a = a | a; 1974 | a = a >= b; 1975 | d = a == c; 1976 | c = d == a; 1977 | d = a + b; 1978 | a = 7; 1979 | c = d << a; 1980 | assert(d == 1); 1981 | c = c > b; 1982 | b = a - c; 1983 | assert(a == 7); 1984 | b = b >> d; 1985 | a = b + c; 1986 | a = d == c; 1987 | c = b == a; 1988 | assert(b == 3); 1989 | d = 200; 1990 | a = 4; 1991 | d = b - c; 1992 | assert(a == 4); 1993 | c = c * d; 1994 | assert(d == 3); 1995 | c = c < a; 1996 | d = c >= a; 1997 | d = d - a; 1998 | a = 23; 1999 | c = d | b; 2000 | assert(c == 255); 2001 | c = c & b; 2002 | a = d ^ d; 2003 | c = c - d; 2004 | c = b <= d; 2005 | assert(d == 252); 2006 | b = d >= c; 2007 | b = -119210; 2008 | b = -31832; 2009 | d = 4; 2010 | a = a >> d; 2011 | d = a != a; 2012 | d = a ^ d; 2013 | b = d - a; 2014 | c = b * c; 2015 | c = a == b; 2016 | assert(c == 1); 2017 | assert(b == 0); 2018 | assert(d == 0); 2019 | assert(b == 0); 2020 | a = d >= d; 2021 | b = a << c; 2022 | b = a - d; 2023 | a = c - a; 2024 | a = c - c; 2025 | b = d | a; 2026 | d = a & c; 2027 | d = c * d; 2028 | c = 261; 2029 | a = b != c; 2030 | b = 113944; 2031 | d = a < b; 2032 | b = d * c; 2033 | c = a << d; 2034 | a = a * a; 2035 | a = 15; 2036 | d = d - a; 2037 | d = 27; 2038 | a = d << d; 2039 | assert(b == 261); 2040 | d = b == b; 2041 | c = c | a; 2042 | a = d == a; 2043 | a = b != b; 2044 | b = c - c; 2045 | b = a << a; 2046 | assert(a == 0); 2047 | d = d & c; 2048 | c = c == b; 2049 | a = b + d; 2050 | a = c == c; 2051 | b = b & a; 2052 | b = d >> b; 2053 | c = c | c; 2054 | d = a != c; 2055 | a = 31; 2056 | b = a != d; 2057 | c = d <= d; 2058 | a = c | b; 2059 | c = c == c; 2060 | assert(d == 1); 2061 | b = b > c; 2062 | a = 29; 2063 | assert(a == 29); 2064 | b = b & c; 2065 | c = -167; 2066 | assert(b == 0); 2067 | a = 6; 2068 | d = a < b; 2069 | c = b & c; 2070 | b = a * b; 2071 | assert(a == 6); 2072 | d = 62; 2073 | b = c + c; 2074 | c = -473; 2075 | a = a >> b; 2076 | d = 246; 2077 | assert(d == 246); 2078 | d = 27; 2079 | b = a >> d; 2080 | b = d - a; 2081 | b = d * d; 2082 | a = c & a; 2083 | a = b != b; 2084 | b = d * a; 2085 | d = b ^ b; 2086 | b = 57398; 2087 | d = a > c; 2088 | c = 408; 2089 | d = c != d; 2090 | b = b - c; 2091 | assert(c == 408); 2092 | c = b ^ b; 2093 | assert(b == 56990); 2094 | assert(d == 1); 2095 | d = a >= c; 2096 | assert(c == 0); 2097 | d = d > a; 2098 | b = 90073; 2099 | b = a > c; 2100 | a = 13; 2101 | a = d >= d; 2102 | c = a >> c; 2103 | d = 186; 2104 | d = 24; 2105 | d = b << d; 2106 | b = b * a; 2107 | b = a == b; 2108 | a = c | d; 2109 | a = a >= b; 2110 | b = -69478; 2111 | d = a ^ d; 2112 | b = a >= a; 2113 | a = d - a; 2114 | assert(b == 1); 2115 | assert(b == 1); 2116 | assert(d == 1); 2117 | d = d <= d; 2118 | d = 255; 2119 | a = b != b; 2120 | a = a - d; 2121 | assert(a == 4294967041); 2122 | a = 30; 2123 | assert(d == 255); 2124 | c = b == c; 2125 | a = c - d; 2126 | assert(c == 1); 2127 | d = d << b; 2128 | a = b * a; 2129 | d = 240; 2130 | d = d != d; 2131 | a = a < a; 2132 | c = 310; 2133 | assert(d == 0); 2134 | d = c - c; 2135 | b = d == a; 2136 | d = c != c; 2137 | a = c | c; 2138 | assert(b == 1); 2139 | assert(a == 310); 2140 | d = c >> d; 2141 | a = a & c; 2142 | c = a * b; 2143 | assert(d == 54); 2144 | assert(b == 1); 2145 | a = 26; 2146 | b = d <= c; 2147 | a = a > b; 2148 | c = a | c; 2149 | d = 1; 2150 | d = c >> d; 2151 | assert(c == 311); 2152 | a = a <= b; 2153 | a = 8; 2154 | assert(c == 311); 2155 | d = c ^ c; 2156 | c = c ^ d; 2157 | assert(b == 1); 2158 | d = a * c; 2159 | a = 18; 2160 | c = d >= b; 2161 | d = c >= a; 2162 | b = b >= c; 2163 | a = b <= d; 2164 | d = a ^ c; 2165 | assert(a == 0); 2166 | c = -421; 2167 | d = c <= c; 2168 | a = c >> d; 2169 | c = 492; 2170 | b = d + a; 2171 | c = -420; 2172 | d = 224; 2173 | c = c & d; 2174 | d = a + d; 2175 | b = 96654; 2176 | b = d << d; 2177 | b = c >= a; 2178 | d = 215; 2179 | assert(c == 64); 2180 | a = 19; 2181 | c = a != b; 2182 | b = d * b; 2183 | assert(d == 215); 2184 | a = c >= d; 2185 | c = -72; 2186 | d = b != c; 2187 | b = -67388; 2188 | d = c != d; 2189 | d = c >> d; 2190 | b = a == a; 2191 | d = a >= c; 2192 | b = b << b; 2193 | d = 56; 2194 | assert(c == -72); 2195 | b = -78217; 2196 | assert(a == 0); 2197 | c = 361; 2198 | c = d == a; 2199 | b = 17; 2200 | d = a << b; 2201 | a = 23; 2202 | b = a >= b; 2203 | a = 8; 2204 | a = a >= a; 2205 | b = c >= d; 2206 | c = b != a; 2207 | a = c + d; 2208 | b = a << d; 2209 | b = b >= a; 2210 | d = b >= c; 2211 | d = c == d; 2212 | assert(a == 0); 2213 | d = a < c; 2214 | d = 95; 2215 | c = c >> c; 2216 | assert(a == 0); 2217 | b = d >= a; 2218 | a = 21; 2219 | b = a >= d; 2220 | a = c + c; 2221 | c = -226; 2222 | c = c < a; 2223 | d = c >= c; 2224 | b = b * a; 2225 | a = a + a; 2226 | b = a >= c; 2227 | c = c | d; 2228 | assert(b == 1); 2229 | c = a & c; 2230 | d = 118; 2231 | c = b + b; 2232 | c = c == d; 2233 | a = d > d; 2234 | d = 8; 2235 | c = -227; 2236 | c = b * a; 2237 | c = a <= c; 2238 | d = c >= d; 2239 | a = d <= c; 2240 | c = -203; 2241 | b = -120323; 2242 | b = 14979; 2243 | a = b * a; 2244 | c = 60; 2245 | d = d | b; 2246 | a = b <= b; 2247 | d = c != c; 2248 | d = 16; 2249 | assert(a == 1); 2250 | c = c <= a; 2251 | c = d + c; 2252 | d = d != a; 2253 | d = 203; 2254 | c = c & b; 2255 | assert(a == 1); 2256 | b = d & a; 2257 | d = a >> c; 2258 | b = b + d; 2259 | a = 28; 2260 | c = b * c; 2261 | assert(c == 0); 2262 | d = a >> d; 2263 | b = a ^ c; 2264 | a = d + c; 2265 | b = d & c; 2266 | assert(a == 14); 2267 | assert(b == 0); 2268 | c = d & a; 2269 | a = b & b; 2270 | a = c | a; 2271 | d = 171; 2272 | d = c == c; 2273 | d = c == c; 2274 | c = c & b; 2275 | a = 4; 2276 | assert(b == 0); 2277 | d = a & c; 2278 | c = b == d; 2279 | c = 362; 2280 | c = b >> d; 2281 | assert(d == 0); 2282 | c = 3; 2283 | a = d & c; 2284 | a = a <= d; 2285 | a = c + c; 2286 | assert(b == 0); 2287 | a = 19; 2288 | a = 29; 2289 | a = a < d; 2290 | d = b > b; 2291 | b = d + d; 2292 | a = c > c; 2293 | a = a < a; 2294 | d = c - d; 2295 | a = c - d; 2296 | c = b == a; 2297 | a = c == c; 2298 | b = b >> b; 2299 | c = a | b; 2300 | b = d >= a; 2301 | c = d <= a; 2302 | c = c * b; 2303 | assert(b == 1); 2304 | a = a < c; 2305 | a = 18; 2306 | b = b <= a; 2307 | d = b ^ c; 2308 | d = d - a; 2309 | a = c * c; 2310 | b = a < b; 2311 | d = 10; 2312 | d = a >> d; 2313 | d = b <= b; 2314 | c = a != a; 2315 | d = 215; 2316 | assert(a == 0); 2317 | c = 234; 2318 | d = c > a; 2319 | d = a >= d; 2320 | assert(a == 0); 2321 | a = b - d; 2322 | c = d | a; 2323 | c = c == d; 2324 | assert(c == 0); 2325 | d = c > a; 2326 | a = 14; 2327 | a = b >> c; 2328 | a = a & c; 2329 | b = -117901; 2330 | b = 118888; 2331 | c = a != c; 2332 | b = b != b; 2333 | c = a | d; 2334 | a = c * a; 2335 | c = d <= b; 2336 | d = b <= c; 2337 | a = b | a; 2338 | d = a & c; 2339 | d = c + d; 2340 | a = d > d; 2341 | c = b ^ d; 2342 | a = c << c; 2343 | c = -30; 2344 | c = b >= d; 2345 | c = 280; 2346 | d = b != b; 2347 | b = a | b; 2348 | assert(d == 0); 2349 | assert(b == 2); 2350 | d = 178; 2351 | assert(c == 280); 2352 | c = c <= a; 2353 | a = d + d; 2354 | a = b ^ c; 2355 | c = 265; 2356 | b = -125091; 2357 | d = d > a; 2358 | d = 82; 2359 | a = b + b; 2360 | d = b == a; 2361 | assert(c == 265); 2362 | a = 2; 2363 | c = b >> a; 2364 | assert(b == -125091); 2365 | b = 87127; 2366 | c = -291; 2367 | d = 26; 2368 | b = c < d; 2369 | d = d + c; 2370 | d = b < a; 2371 | b = a != a; 2372 | a = b + d; 2373 | c = b & d; 2374 | c = d << a; 2375 | b = a + d; 2376 | c = c + c; 2377 | assert(c == 4); 2378 | b = d << c; 2379 | assert(d == 1); 2380 | c = b + a; 2381 | assert(a == 1); 2382 | c = b >= b; 2383 | d = a != d; 2384 | a = b & b; 2385 | assert(c == 1); 2386 | d = b & a; 2387 | a = 16; 2388 | a = a | b; 2389 | a = b ^ d; 2390 | c = b < c; 2391 | a = 29; 2392 | d = b >= d; 2393 | b = -20555; 2394 | b = b - a; 2395 | b = b <= a; 2396 | c = a <= d; 2397 | a = c != b; 2398 | c = b == b; 2399 | c = 319; 2400 | d = a >> a; 2401 | assert(a == 0); 2402 | a = c <= a; 2403 | a = b ^ b; 2404 | b = a != b; 2405 | a = c <= b; 2406 | b = b << b; 2407 | b = a ^ d; 2408 | c = b >= b; 2409 | a = c + d; 2410 | d = c ^ c; 2411 | a = c & b; 2412 | d = 184; 2413 | a = a << c; 2414 | a = c >= d; 2415 | d = a != b; 2416 | d = 23; 2417 | a = 15; 2418 | d = d - d; 2419 | a = a + d; 2420 | assert(a == 15); 2421 | c = b | c; 2422 | c = c != c; 2423 | d = a | c; 2424 | c = a >> b; 2425 | b = a & a; 2426 | d = 119; 2427 | a = d < b; 2428 | c = 161; 2429 | c = c & b; 2430 | a = d != a; 2431 | a = b != a; 2432 | assert(c == 1); 2433 | assert(b == 15); 2434 | assert(b == 15); 2435 | b = 110154; 2436 | d = d * b; 2437 | d = 248; 2438 | assert(a == 1); 2439 | a = a ^ a; 2440 | b = c != a; 2441 | b = d > d; 2442 | b = d >> a; 2443 | c = b + b; 2444 | a = b >= d; 2445 | c = c | d; 2446 | b = b - c; 2447 | b = a > a; 2448 | assert(c == 504); 2449 | assert(d == 248); 2450 | c = c == d; 2451 | b = -122854; 2452 | a = d | a; 2453 | a = a == b; 2454 | c = b >= b; 2455 | c = a ^ a; 2456 | a = c * c; 2457 | a = 5; 2458 | a = c | a; 2459 | c = -226; 2460 | a = 24; 2461 | assert(a == 24); 2462 | d = a + a; 2463 | a = d - a; 2464 | assert(b == -122854); 2465 | d = d <= d; 2466 | b = 22; 2467 | b = a << b; 2468 | b = 48071; 2469 | c = a & d; 2470 | a = b + a; 2471 | a = 14; 2472 | b = -121884; 2473 | assert(b == -121884); 2474 | assert(c == 0); 2475 | a = a > a; 2476 | b = 110250; 2477 | b = c * c; 2478 | a = a <= b; 2479 | a = 26; 2480 | b = a != d; 2481 | d = b * d; 2482 | a = a < c; 2483 | assert(a == 0); 2484 | c = d ^ b; 2485 | a = a <= c; 2486 | a = 6; 2487 | d = 162; 2488 | c = b + a; 2489 | d = d >= c; 2490 | assert(d == 1); 2491 | b = b < d; 2492 | assert(a == 6); 2493 | assert(c == 7); 2494 | a = d > a; 2495 | b = b >= c; 2496 | c = -9; 2497 | d = a & b; 2498 | d = c & d; 2499 | c = -480; 2500 | b = b & a; 2501 | b = a < d; 2502 | b = d == d; 2503 | assert(d == 0); 2504 | d = a != a; 2505 | assert(a == 0); 2506 | c = c > c; 2507 | c = a | a; 2508 | a = b != b; 2509 | b = b ^ a; 2510 | assert(a == 0); 2511 | c = b ^ c; 2512 | c = d - c; 2513 | c = a >> d; 2514 | b = c | d; 2515 | d = a < c; 2516 | b = -106323; 2517 | a = c - b; 2518 | assert(b == -106323); 2519 | d = c | b; 2520 | a = 3; 2521 | c = c < a; 2522 | a = a * d; 2523 | b = a & c; 2524 | c = d << b; 2525 | assert(b == 1); 2526 | c = -477; 2527 | d = c & d; 2528 | a = 19; 2529 | assert(c == -477); 2530 | c = b * a; 2531 | a = b == c; 2532 | b = -8396; 2533 | assert(a == 0); 2534 | a = b == a; 2535 | assert(a == 0); 2536 | c = c + b; 2537 | a = 19; 2538 | d = 6; 2539 | c = d > b; 2540 | c = d << c; 2541 | a = 20; 2542 | assert(d == 6); 2543 | a = d << a; 2544 | b = d << d; 2545 | c = b | d; 2546 | c = a - a; 2547 | b = a | b; 2548 | c = d | c; 2549 | c = 233; 2550 | c = d > c; 2551 | a = 2; 2552 | b = d >> a; 2553 | c = b + b; 2554 | b = c + d; 2555 | d = 182; 2556 | b = d - c; 2557 | assert(b == 180); 2558 | b = c > a; 2559 | a = 6; 2560 | c = -158; 2561 | b = c | d; 2562 | c = c | c; 2563 | a = c - c; 2564 | a = c + d; 2565 | c = c != d; 2566 | b = c + c; 2567 | d = 101; 2568 | c = c * a; 2569 | assert(d == 101); 2570 | d = b & a; 2571 | b = a + c; 2572 | d = c << a; 2573 | a = b != b; 2574 | c = d <= b; 2575 | b = b != c; 2576 | c = -444; 2577 | d = 36; 2578 | b = d == d; 2579 | a = a >> b; 2580 | b = b | a; 2581 | c = 324; 2582 | assert(d == 36); 2583 | d = d * c; 2584 | b = c | d; 2585 | d = 24; 2586 | c = d | b; 2587 | d = d * a; 2588 | c = b >= a; 2589 | assert(b == 468); 2590 | b = 12; 2591 | c = a >> b; 2592 | c = b < a; 2593 | b = c + c; 2594 | c = d << c; 2595 | d = d * c; 2596 | b = d & c; 2597 | b = 57371; 2598 | c = b == b; 2599 | b = c == c; 2600 | assert(d == 0); 2601 | a = 12; 2602 | c = d < a; 2603 | c = c != a; 2604 | d = b >> d; 2605 | assert(b == 1); 2606 | assert(a == 12); 2607 | a = c & d; 2608 | a = b | c; 2609 | c = -463; 2610 | assert(c == -463); 2611 | c = -410; 2612 | d = d != c; 2613 | b = c <= c; 2614 | a = 17; 2615 | c = c != c; 2616 | a = a ^ b; 2617 | b = b << a; 2618 | d = 200; 2619 | b = c - c; 2620 | d = d + d; 2621 | b = a + d; 2622 | a = c | d; 2623 | a = 16; 2624 | d = a & c; 2625 | c = d >> d; 2626 | b = c >= a; 2627 | d = b >> b; 2628 | c = b & b; 2629 | a = d | d; 2630 | a = b >= c; 2631 | d = c * d; 2632 | a = b <= d; 2633 | b = b >> d; 2634 | b = 101550; 2635 | a = c + b; 2636 | d = 70; 2637 | d = 148; 2638 | assert(b == 101550); 2639 | d = 146; 2640 | d = d < d; 2641 | d = a > b; 2642 | d = c * a; 2643 | assert(c == 0); 2644 | b = d >= b; 2645 | d = d & b; 2646 | a = 30; 2647 | c = d - d; 2648 | d = c >> b; 2649 | b = b + c; 2650 | d = 160; 2651 | a = d > c; 2652 | assert(d == 160); 2653 | c = b & c; 2654 | c = c >> c; 2655 | b = b << a; 2656 | b = c & d; 2657 | a = d != b; 2658 | d = d > b; 2659 | b = a - d; 2660 | a = 23; 2661 | assert(d == 1); 2662 | d = b ^ b; 2663 | assert(d == 0); 2664 | b = a == d; 2665 | d = d ^ c; 2666 | c = a <= d; 2667 | a = b >> c; 2668 | assert(b == 0); 2669 | b = c ^ c; 2670 | c = a > a; 2671 | c = b < a; 2672 | d = d <= b; 2673 | c = b ^ b; 2674 | assert(d == 1); 2675 | a = c < b; 2676 | b = -121388; 2677 | a = d & a; 2678 | b = d <= a; 2679 | a = b + b; 2680 | c = a & c; 2681 | assert(d == 1); 2682 | d = a << c; 2683 | assert(d == 0); 2684 | assert(c == 0); 2685 | b = c << c; 2686 | b = d != a; 2687 | a = d + a; 2688 | d = c - b; 2689 | b = -112299; 2690 | d = d > b; 2691 | c = b | d; 2692 | assert(a == 0); 2693 | b = d * b; 2694 | d = b >= c; 2695 | b = c ^ c; 2696 | assert(a == 0); 2697 | a = b <= b; 2698 | d = b * a; 2699 | assert(d == 0); 2700 | b = d ^ a; 2701 | assert(b == 1); 2702 | a = b ^ c; 2703 | b = d + c; 2704 | b = d < b; 2705 | b = c | a; 2706 | assert(a == 4294854996); 2707 | d = d ^ c; 2708 | a = c != a; 2709 | assert(a == 1); 2710 | assert(d == 85); 2711 | assert(d == 85); 2712 | assert(d == 85); 2713 | d = b > c; 2714 | assert(d == 0); 2715 | c = 210; 2716 | a = c + b; 2717 | assert(c == 210); 2718 | d = a ^ b; 2719 | assert(c == 210); 2720 | b = d != a; 2721 | d = c != c; 2722 | a = 25; 2723 | d = b * d; 2724 | b = a ^ a; 2725 | assert(b == 0); 2726 | assert(d == 0); 2727 | c = 7; 2728 | b = d >> c; 2729 | b = a ^ d; 2730 | c = d ^ a; 2731 | c = 279; 2732 | a = 6; 2733 | assert(d == 0); 2734 | d = a != c; 2735 | a = b * d; 2736 | b = 116370; 2737 | assert(b == 116370); 2738 | b = d < c; 2739 | assert(b == 1); 2740 | d = d - a; 2741 | b = b * d; 2742 | b = a != d; 2743 | a = b != a; 2744 | b = b < c; 2745 | a = c >= b; 2746 | b = c > a; 2747 | d = b == d; 2748 | assert(d == 0); 2749 | b = d | d; 2750 | a = a > d; 2751 | b = b <= c; 2752 | c = d > c; 2753 | d = a != b; 2754 | c = b < b; 2755 | assert(d == 0); 2756 | d = 115; 2757 | a = d >> a; 2758 | b = 41545; 2759 | c = c - c; 2760 | d = c ^ c; 2761 | b = -22665; 2762 | c = d | c; 2763 | a = a - d; 2764 | a = a ^ c; 2765 | b = d < c; 2766 | b = c >= c; 2767 | b = d | d; 2768 | d = c ^ c; 2769 | b = d ^ b; 2770 | d = d << d; 2771 | assert(d == 0); 2772 | c = a > a; 2773 | c = c >> c; 2774 | assert(d == 0); 2775 | b = a != d; 2776 | a = 25; 2777 | c = a >= b; 2778 | b = c > a; 2779 | assert(c == 1); 2780 | assert(b == 0); 2781 | b = c * c; 2782 | assert(c == 1); 2783 | c = b >= d; 2784 | d = c <= b; 2785 | b = c < a; 2786 | c = a + b; 2787 | c = d == d; 2788 | assert(c == 1); 2789 | assert(a == 25); 2790 | d = 163; 2791 | b = 90909; 2792 | assert(a == 25); 2793 | d = a - d; 2794 | c = a - a; 2795 | d = d < c; 2796 | b = a ^ b; 2797 | c = b - b; 2798 | assert(b == 90884); 2799 | b = 4; 2800 | d = c << b; 2801 | b = b == a; 2802 | assert(d == 0); 2803 | assert(a == 25); 2804 | b = a > d; 2805 | c = -185; 2806 | b = a >> a; 2807 | assert(d == 0); 2808 | b = d >= d; 2809 | d = 196; 2810 | d = b ^ b; 2811 | c = d > d; 2812 | b = c & b; 2813 | a = 15; 2814 | assert(d == 0); 2815 | assert(d == 0); 2816 | d = b <= c; 2817 | c = c * c; 2818 | d = c << c; 2819 | c = 26; 2820 | assert(b == 0); 2821 | b = -115406; 2822 | c = d << a; 2823 | c = a >= b; 2824 | b = 7; 2825 | a = a >> b; 2826 | c = a + a; 2827 | assert(b == 7); 2828 | d = 72; 2829 | d = 149; 2830 | b = d - a; 2831 | b = -124671; 2832 | b = 88677; 2833 | b = a * b; 2834 | d = a >> c; 2835 | d = b - d; 2836 | a = d != c; 2837 | b = b != b; 2838 | a = 24; 2839 | a = d + a; 2840 | d = b <= a; 2841 | c = b * a; 2842 | d = c * c; 2843 | b = c < c; 2844 | d = c >> a; 2845 | d = b >= a; 2846 | b = d >> c; 2847 | b = c | c; 2848 | d = a & d; 2849 | assert(b == 0); 2850 | d = b != a; 2851 | c = d & d; 2852 | a = d << d; 2853 | c = c << d; 2854 | c = -227; 2855 | c = 3; 2856 | b = c >> c; 2857 | a = c == b; 2858 | a = c < b; 2859 | c = c == b; 2860 | c = a < b; 2861 | d = d <= a; 2862 | a = d > b; 2863 | c = -262; 2864 | d = b - d; 2865 | d = 246; 2866 | a = a != d; 2867 | b = d * c; 2868 | d = c > a; 2869 | assert(d == 1); 2870 | b = -20944; 2871 | b = c * b; 2872 | a = b & b; 2873 | d = 7; 2874 | assert(c == -262); 2875 | d = b + b; 2876 | c = b & c; 2877 | b = -123690; 2878 | assert(c == 5487328); 2879 | b = b * a; 2880 | a = d < c; 2881 | a = d < a; 2882 | a = a | a; 2883 | c = 432; 2884 | a = b == c; 2885 | a = 4; 2886 | assert(a == 4); 2887 | c = d >= a; 2888 | b = b ^ a; 2889 | b = d - c; 2890 | b = d & c; 2891 | c = 286; 2892 | d = a - a; 2893 | c = d >> b; 2894 | a = d & c; 2895 | c = a + b; 2896 | c = b * d; 2897 | a = a & a; 2898 | c = c <= b; 2899 | c = a <= c; 2900 | d = b <= d; 2901 | assert(c == 1); 2902 | assert(c == 1); 2903 | b = -53217; 2904 | b = d == a; 2905 | b = c > d; 2906 | c = b < b; 2907 | c = 439; 2908 | c = -405; 2909 | a = d < b; 2910 | assert(a == 0); 2911 | b = d < b; 2912 | c = 7; 2913 | a = c << c; 2914 | a = c ^ a; 2915 | d = a + d; 2916 | assert(a == 903); 2917 | c = c != d; 2918 | c = a >> b; 2919 | c = c * c; 2920 | assert(a == 903); 2921 | a = c & a; 2922 | assert(a == 257); 2923 | b = a & a; 2924 | b = 8; 2925 | b = d << b; 2926 | a = a | b; 2927 | a = a > a; 2928 | c = a & b; 2929 | c = 169; 2930 | d = c | c; 2931 | d = 166; 2932 | d = d ^ d; 2933 | d = d > d; 2934 | assert(d == 0); 2935 | d = c > d; 2936 | c = c != c; 2937 | d = a > b; 2938 | assert(c == 0); 2939 | a = a - a; 2940 | b = -101674; 2941 | c = c << c; 2942 | d = d == a; 2943 | b = b - b; 2944 | a = 2; 2945 | b = 11426; 2946 | a = c & a; 2947 | a = b >= c; 2948 | c = d + b; 2949 | c = a ^ b; 2950 | b = d * b; 2951 | b = -84480; 2952 | assert(d == 1); 2953 | d = a >= d; 2954 | assert(b == -84480); 2955 | a = c >= a; 2956 | d = c >= d; 2957 | a = b == c; 2958 | a = d > c; 2959 | b = b ^ d; 2960 | c = c - a; 2961 | assert(c == 11427); 2962 | assert(a == 0); 2963 | d = d + b; 2964 | b = c << d; 2965 | b = d & a; 2966 | c = d > d; 2967 | a = d == a; 2968 | a = 14; 2969 | b = a >> d; 2970 | b = b ^ b; 2971 | c = b == b; 2972 | d = a == c; 2973 | d = a < a; 2974 | c = -112; 2975 | c = b ^ a; 2976 | c = 32; 2977 | b = 78442; 2978 | b = d == d; 2979 | c = d <= d; 2980 | d = 143; 2981 | c = c & c; 2982 | a = 30; 2983 | assert(a == 30); 2984 | assert(b == 1); 2985 | d = c > a; 2986 | d = c & a; 2987 | c = c | c; 2988 | d = 89; 2989 | d = 11; 2990 | c = d >> d; 2991 | d = c < d; 2992 | c = -300; 2993 | b = b < d; 2994 | c = a + c; 2995 | a = c > d; 2996 | d = a < a; 2997 | a = 14; 2998 | a = d >= a; 2999 | d = 247; 3000 | a = d * c; 3001 | a = 8; 3002 | a = d <= d; 3003 | assert(b == 0); 3004 | c = c <= d; 3005 | a = 15; 3006 | a = b <= a; 3007 | a = b * d; 3008 | c = c + c; 3009 | d = a < b; 3010 | c = b * a; 3011 | d = 100; 3012 | c = d ^ d; 3013 | a = d & c; 3014 | a = c == c; 3015 | b = 103749; 3016 | d = 4; 3017 | a = b == c; 3018 | assert(a == 0); 3019 | d = c | c; 3020 | c = d * b; 3021 | d = 34; 3022 | c = b > c; 3023 | d = 2; 3024 | a = d >> d; 3025 | c = b << c; 3026 | c = 71; 3027 | a = 22; 3028 | d = 87; 3029 | b = d != a; 3030 | assert(c == 71); 3031 | assert(d == 87); 3032 | c = d & d; 3033 | d = c + c; 3034 | b = c - a; 3035 | d = a ^ c; 3036 | d = d * b; 3037 | a = a * a; 3038 | a = 24; 3039 | d = d >> a; 3040 | d = a > c; 3041 | c = -459; 3042 | assert(d == 0); 3043 | c = -286; 3044 | d = c & a; 3045 | a = b < a; 3046 | assert(d == 0); 3047 | d = d & c; 3048 | a = d == a; 3049 | a = b | b; 3050 | a = 9; 3051 | b = 28841; 3052 | d = d <= c; 3053 | b = d - b; 3054 | a = c > c; 3055 | a = d <= d; 3056 | assert(a == 1); 3057 | a = d & a; 3058 | a = 14; 3059 | assert(a == 14); 3060 | b = b == b; 3061 | d = c | c; 3062 | c = b * a; 3063 | a = b < b; 3064 | d = c >= b; 3065 | a = 32; 3066 | a = a | b; 3067 | c = d & d; 3068 | d = c & c; 3069 | b = a * d; 3070 | assert(b == 33); 3071 | assert(c == 1); 3072 | c = -468; 3073 | a = 24; 3074 | b = a >> a; 3075 | d = d - b; 3076 | assert(d == 1); 3077 | assert(a == 24); 3078 | a = 9; 3079 | d = c & a; 3080 | a = d == b; 3081 | b = b >> a; 3082 | a = 3; 3083 | a = d | b; 3084 | b = -43775; 3085 | c = b >= b; 3086 | d = d < b; 3087 | c = c < a; 3088 | b = 58929; 3089 | d = d != c; 3090 | assert(c == 1); 3091 | assert(a == 8); 3092 | d = d - c; 3093 | c = b * a; 3094 | c = a - b; 3095 | b = d ^ c; 3096 | assert(b == -58921); 3097 | assert(b == -58921); 3098 | d = c > c; 3099 | b = 1; 3100 | d = a << b; 3101 | d = b | c; 3102 | d = a ^ c; 3103 | d = a == a; 3104 | d = b > a; 3105 | b = b - a; 3106 | b = b ^ c; 3107 | assert(b == 58926); 3108 | assert(d == 0); 3109 | b = -52368; 3110 | d = a == d; 3111 | b = c ^ d; 3112 | d = 7; 3113 | assert(d == 7); 3114 | c = a > d; 3115 | assert(a == 8); 3116 | a = 32; 3117 | assert(a == 32); 3118 | d = d == c; 3119 | c = -351; 3120 | b = a - c; 3121 | a = b * d; 3122 | c = 80; 3123 | d = 137; 3124 | b = d <= c; 3125 | d = 12; 3126 | d = d >> d; 3127 | a = 16; 3128 | b = d << b; 3129 | d = b < d; 3130 | b = b + b; 3131 | d = d | a; 3132 | assert(a == 16); 3133 | d = a & d; 3134 | b = a << a; 3135 | a = d - a; 3136 | assert(c == 80); 3137 | assert(c == 80); 3138 | b = c == b; 3139 | a = d >= c; 3140 | d = d > b; 3141 | c = b - b; 3142 | b = c <= d; 3143 | assert(c == 0); 3144 | assert(b == 1); 3145 | a = d - a; 3146 | a = c ^ b; 3147 | b = b != b; 3148 | assert(b == 0); 3149 | b = b - b; 3150 | d = d >> b; 3151 | c = a >= d; 3152 | a = d >> b; 3153 | a = d ^ a; 3154 | b = d == b; 3155 | a = c - d; 3156 | c = d | c; 3157 | a = a != d; 3158 | b = d - d; 3159 | b = a << c; 3160 | c = c == d; 3161 | a = 2; 3162 | assert(c == 1); 3163 | assert(a == 2); 3164 | a = 9; 3165 | a = 32; 3166 | c = b * c; 3167 | a = 5; 3168 | d = b == b; 3169 | b = d & a; 3170 | b = a & c; 3171 | b = b & d; 3172 | assert(c == 2); 3173 | d = 216; 3174 | d = d | b; 3175 | assert(d == 216); 3176 | a = c & d; 3177 | a = c >= d; 3178 | b = d >= b; 3179 | a = a + b; 3180 | assert(c == 2); 3181 | a = c + d; 3182 | c = -233; 3183 | d = 71; 3184 | assert(a == 218); 3185 | d = d >> b; 3186 | b = -28080; 3187 | a = 17; 3188 | d = c >> a; 3189 | a = a > d; 3190 | c = 278; 3191 | d = c + d; 3192 | c = c + c; 3193 | b = c <= a; 3194 | d = a > c; 3195 | assert(b == 0); 3196 | assert(a == 0); 3197 | c = c == c; 3198 | b = b - c; 3199 | c = b < a; 3200 | a = c != d; 3201 | a = b < c; 3202 | b = 119522; 3203 | d = a >= d; 3204 | assert(b == 119522); 3205 | a = a - d; 3206 | b = d * c; 3207 | b = 39426; 3208 | a = c <= c; 3209 | c = b == b; 3210 | c = d <= b; 3211 | d = d * b; 3212 | a = 12; 3213 | d = 61; 3214 | assert(b == 39426); 3215 | c = c < a; 3216 | assert(b == 39426); 3217 | d = 148; 3218 | d = a + b; 3219 | b = d * b; 3220 | assert(d == 14); 3221 | a = a - b; 3222 | d = c < b; 3223 | d = c + b; 3224 | a = b >= c; 3225 | d = a | a; 3226 | b = d >> d; 3227 | assert(d == 1); 3228 | c = a << b; 3229 | assert(a == 1); 3230 | d = 49; 3231 | d = 18; 3232 | c = a << d; 3233 | a = c <= c; 3234 | b = a & b; 3235 | a = c <= d; 3236 | c = 28; 3237 | d = b << c; 3238 | d = d == d; 3239 | b = d != b; 3240 | b = 26350; 3241 | assert(b == 26350); 3242 | a = d ^ b; 3243 | b = c + b; 3244 | a = d >= c; 3245 | assert(c == 28); 3246 | b = -16458; 3247 | assert(c == 28); 3248 | a = a == c; 3249 | b = 5; 3250 | b = c >> b; 3251 | d = a >> c; 3252 | a = c <= b; 3253 | b = a >= b; 3254 | c = -318; 3255 | d = d == a; 3256 | d = b >= c; 3257 | d = d << b; 3258 | a = 6; 3259 | a = b & b; 3260 | a = 18; 3261 | b = -60040; 3262 | a = 29; 3263 | d = d & b; 3264 | c = 205; 3265 | c = d ^ c; 3266 | b = 125689; 3267 | a = c * d; 3268 | b = c != c; 3269 | b = c == a; 3270 | a = c > c; 3271 | assert(d == 0); 3272 | a = d <= c; 3273 | a = d != a; 3274 | c = b != b; 3275 | b = 96024; 3276 | b = -126168; 3277 | b = c <= d; 3278 | a = c ^ c; 3279 | b = d > a; 3280 | c = d != c; 3281 | assert(c == 0); 3282 | d = d != b; 3283 | a = a | b; 3284 | c = -328; 3285 | a = c == d; 3286 | c = c - b; 3287 | b = 2929; 3288 | b = 28202; 3289 | assert(d == 0); 3290 | c = d | c; 3291 | assert(d == 0); 3292 | a = a > d; 3293 | c = 283; 3294 | assert(a == 0); 3295 | c = b == b; 3296 | b = c ^ c; 3297 | assert(d == 0); 3298 | d = d > a; 3299 | assert(a == 0); 3300 | b = d == c; 3301 | c = 366; 3302 | b = c - a; 3303 | b = d & d; 3304 | c = d - c; 3305 | d = c + b; 3306 | c = -407; 3307 | b = c - a; 3308 | assert(a == 0); 3309 | c = d ^ d; 3310 | assert(c == 0); 3311 | a = d < c; 3312 | b = a != c; 3313 | d = c != a; 3314 | c = d ^ a; 3315 | c = c > a; 3316 | c = c - c; 3317 | b = 101885; 3318 | c = c >= b; 3319 | d = a ^ a; 3320 | d = a >= a; 3321 | b = a | b; 3322 | c = b * c; 3323 | a = b << d; 3324 | assert(c == 0); 3325 | a = 26; 3326 | d = b >> a; 3327 | a = a | d; 3328 | assert(d == 0); 3329 | a = c + b; 3330 | c = c ^ d; 3331 | a = b & c; 3332 | d = d < c; 3333 | c = a - b; 3334 | d = c + c; 3335 | a = a < b; 3336 | assert(d == 6); 3337 | d = d >= d; 3338 | d = a >= a; 3339 | c = a - d; 3340 | c = 48; 3341 | c = a ^ b; 3342 | b = -45809; 3343 | b = 12; 3344 | d = d >> b; 3345 | a = c > d; 3346 | c = c << a; 3347 | assert(d == 0); 3348 | assert(a == 1); 3349 | d = 119; 3350 | a = d >= a; 3351 | assert(d == 119); 3352 | func2_count += 1; 3353 | } 3354 | 3355 | return 0; 3356 | } 3357 | 3358 | --------------------------------------------------------------------------------