TEST(plankton, env_construction) { CREATE_RUNTIME(); // Environment references resolve correctly to ast factories. { byte_buffer_t buf; byte_buffer_init(&buf); write_ast_factory(&buf, "Literal"); value_t value = deserialize(runtime, &buf); ASSERT_FAMILY(ofFactory, value); byte_buffer_dispose(&buf); } // Objects with ast factory headers produce asts. { byte_buffer_t buf; byte_buffer_init(&buf); byte_buffer_append(&buf, pObject); write_ast_factory(&buf, "Literal"); byte_buffer_append(&buf, pMap); plankton_wire_encode_uint32(&buf, 1); write_string(&buf, "value"); byte_buffer_append(&buf, pTrue); value_t value = deserialize(runtime, &buf); ASSERT_FAMILY(ofLiteralAst, value); ASSERT_VALEQ(yes(), get_literal_ast_value(value)); byte_buffer_dispose(&buf); } DISPOSE_RUNTIME(); }
value_t read_handle_to_blob(runtime_t *runtime, FILE *handle) { // Read the complete file into a byte buffer. byte_buffer_t buffer; byte_buffer_init(&buffer); while (true) { static const size_t kBufSize = 1024; byte_t raw_buffer[kBufSize]; size_t was_read = fread(raw_buffer, 1, kBufSize, handle); if (was_read <= 0) break; for (size_t i = 0; i < was_read; i++) byte_buffer_append(&buffer, raw_buffer[i]); } blob_t data_blob; byte_buffer_flush(&buffer, &data_blob); // Create a blob to hold the result and copy the data into it. value_t result = new_heap_blob_with_data(runtime, &data_blob); byte_buffer_dispose(&buffer); return result; }
static void do_client_state_machine(const apr_pollfd_t *s, apr_pollset_t *pollset) { struct per_client *c = s->client_data; apr_socket_t *client = s->desc.s; per_client_state old_state = c->state, new_state; apr_int16_t old_reqevents = s->reqevents, new_reqevents; apr_int16_t send_reqevents = APR_POLLOUT | APR_POLLHUP | APR_POLLERR; apr_int16_t recv_reqevents = APR_POLLIN | APR_POLLHUP | APR_POLLERR; byte_buffer *q = &c->query; switch (old_state) { case LM_S_INIT_CLIENT: { DEBUG("LM_S_INIT_CLIENT\n"); new_state = LM_S_SEND_HI; new_reqevents = send_reqevents; c->bytes_sent = 0; byte_buffer_init(&c->query); byte_buffer_init(&c->reply); break; } case LM_S_SEND_HI: { DEBUG("LM_S_SEND_HI\n"); apr_size_t send_sz = (sizeof LM_SERVER_HI) - c->bytes_sent; apr_status_t send_err; send_err = apr_socket_send(client, LM_SERVER_HI, &send_sz); if (send_err && !(APR_STATUS_IS_EAGAIN(send_err))) { APR_FAIL(send_err); new_state = LM_S_CLOSING; break; } c->bytes_sent += send_sz; if (c->bytes_sent == (sizeof LM_SERVER_HI)) { new_state = LM_S_GET_QUERY; new_reqevents = recv_reqevents; } else { new_state = LM_S_SEND_HI; new_reqevents = send_reqevents; } break; } case LM_S_GET_QUERY: { DEBUG("LM_S_GET_QUERY\n"); apr_status_t recv_err; size_t bigger = q->used + 64; if (q->size < bigger) { if (byte_buffer_grow_to(&c->query, bigger)) { FAIL("can't grow receive buffer\n"); new_state = LM_S_CLOSING; break; } } char *put_bytes_here = q->buf + q->used; apr_size_t bytes_read = q->size - q->used; DEBUG("put_bytes_here = %p\n", put_bytes_here); recv_err = apr_socket_recv(client, put_bytes_here, &bytes_read); DEBUG("recv %zu bytes, %d.\n", bytes_read, recv_err); if ((bytes_read == 0) || (APR_STATUS_IS_EOF(recv_err))) { if (q->used == 0) { DEBUG("clean disconnect :)\n"); } else { DEBUG("dirty disconnect :| (%zd)\n", q->used); } new_state = LM_S_CLOSING; break; } if (recv_err) { APR_FAIL(recv_err); new_state = LM_S_CLOSING; break; } q->used += bytes_read; char *null_here; do_you_want_to_try_a_query: null_here = memchr(q->buf, '\x00', q->used); if (null_here) { new_state = LM_S_SEND_REPLY; new_reqevents = send_reqevents; bytes query_bytes; query_bytes.start = c->query.buf; query_bytes.end = null_here; if (do_client_query(c->lmdb, query_bytes, &c->reply)) { new_state = LM_S_CLOSING; break; } /* How many bytes of the buffered input did that */ /* query occupy? Copy any leftovers back up to */ /* the beginning of the 'query' buffer. */ size_t q_consumed = 1 + null_here - c->query.buf; q->used -= q_consumed; if (q->used) { memcpy(q->buf, 1 + null_here, q->used); } c->bytes_sent = 0; if (c->reply.used == 0) { goto do_you_want_to_try_a_query; } } else { new_state = LM_S_GET_QUERY; new_reqevents = recv_reqevents; } break; } case LM_S_SEND_REPLY: { DEBUG("LM_S_SEND_REPLY\n"); apr_size_t nbytes = c->reply.used - c->bytes_sent; char *bytes = c->reply.buf + c->bytes_sent; apr_status_t send_err = apr_socket_send(client, bytes, &nbytes); if (send_err && !(APR_STATUS_IS_EAGAIN(send_err))) { APR_FAIL(send_err); new_state = LM_S_CLOSING; break; } c->bytes_sent += nbytes; if (c->bytes_sent == c->reply.used) { goto do_you_want_to_try_a_query; } else { new_state = LM_S_SEND_REPLY; new_reqevents = send_reqevents; } break; } default: { FAIL("Invalid client state.\n"); abort(); break; } } if (new_state == LM_S_CLOSING) { apr_pollset_remove(pollset, s); apr_socket_close(s->desc.s); byte_buffer_free(&c->query); byte_buffer_free(&c->reply); } else if (old_reqevents != new_reqevents) { apr_pollfd_t s1; memset(&s1, 0, sizeof s1); s1.p = s->p; s1.client_data = s->client_data; s1.desc_type = s->desc_type; s1.desc.s = s->desc.s; s1.reqevents = new_reqevents; apr_pollset_remove(pollset, s); apr_pollset_add(pollset, &s1); } c->state = new_state; }
/// /// Application entry function. Sets up data strctures and threads. /// void cyg_user_start() { struct udp_connection *con; // cyg_sem_t *sem_array[8]; reconos_res_t sem_array_laplace[8]; reconos_res_t sem_array_display[8]; int i; #if defined(USE_DCACHE) // enable caches for DRAM XCache_EnableDCache(0x80000000); #endif diag_printf("Hello embedded world!\n" "This is " __FILE__ " (ReconOS), built " __DATE__ ", " __TIME__ "\n"); // initialize hardware diag_printf("Initializing hardware...\n"); init(); // initialize image buffers diag_printf("Initializing image buffers...\n"); for (i = 0; i < 2; i++) { byte_buffer_init(&input_buffer[i], WIDTH, HEIGHT); // one image + four lines (???) byte_buffer_fill(&input_buffer[i], 0); byte_buffer_init(&laplace_buffer[i], WIDTH, HEIGHT); // one image byte_buffer_fill(&laplace_buffer[i], 0); } // initialize fake output image buffer output_buffer[0].width = WIDTH; // irrelevant output_buffer[0].height = HEIGHT; // irrelevant output_buffer[0].data = fb_info.fb; // this points to the VGA frame buffer // NOTE: the semaphores of this buffer are not used and therefore not initialized diag_printf ("Buffer addresses: input: 0x%08X, laplace: 0x%08X, output: 0x%08X\n", input_buffer[0].data, laplace_buffer[0].data, output_buffer[0].data); // set up UDP connection diag_printf("Setting up UDP networking...\n"); con = udp_connection_create(inet_addr("192.168.1.2")); // initialize thread info structures diag_printf("Initializing thread info structures...\n"); buffer_thread_info_init(&input_thread_info, 2, NULL, input_buffer);/*, NULL, &laplace_rdy, NULL, &input_new);*/ buffer_thread_info_init(&laplace_thread_info, 2, input_buffer, laplace_buffer);/*, &laplace_rdy, &display_rdy, &input_new, &laplace_new);*/ buffer_thread_info_init(&display_thread_info, 2, laplace_buffer, output_buffer);/*, &display_rdy, NULL, &laplace_new, NULL);*/ // initialize semaphores /* diag_printf("Initializing semaphores...\n"); cyg_semaphore_init(&input_new, 0); cyg_semaphore_init(&laplace_rdy, 1); cyg_semaphore_init(&laplace_new, 0); cyg_semaphore_init(&display_rdy, 1);*/ // pass connection info to input thread input_thread_info.data = (cyg_addrword_t) con; diag_printf("Creating threads..."); // create input thread diag_printf("input..."); cyg_thread_create(16, // scheduling info (eg pri) entry_buffer_recv, // entry point function (cyg_addrword_t) & input_thread_info, // entry data "INPUT THREAD", // optional thread name input_stack, // stack base MYTHREAD_STACK_SIZE, // stack size, &input_handle, // returned thread handle &input_thread // put thread here ); #if !defined(USE_HW_LAPLACE) // create laplace software thread diag_printf("laplace_sw..."); cyg_thread_create(16, // scheduling info (eg pri) entry_buffer_laplace, // entry point function (cyg_addrword_t) & laplace_thread_info, // entry data "LAPLACE THREAD (SW)", // optional thread name laplace_stack, // stack base MYTHREAD_STACK_SIZE, // stack size, &laplace_handle, // returned thread handle &laplace_thread // put thread here ); #else // create laplace hardware thread diag_printf("laplace_hw..."); fill_sem_array(sem_array_laplace, &laplace_thread_info); rthread_attr_init(&laplace_hwthread_attr); rthread_attr_setslotnum(&laplace_hwthread_attr, 0); rthread_attr_setresources(&laplace_hwthread_attr, sem_array_laplace, 8); reconos_hwthread_create(16, // scheduling info (eg pri) &laplace_hwthread_attr, // hw thread attributes shm_init(&laplace_thread_info), // init data "LAPLACE_THREAD (HW)", // optional thread name laplace_stack, // stack base MYTHREAD_STACK_SIZE, // stack size, &laplace_handle, // returned thread handle &laplace_hwthread); // put thread here #endif #if !defined(USE_HW_DISPLAY) // create display software thread diag_printf("display_sw..."); cyg_thread_create(16, // scheduling info (eg pri) entry_buffer_display, // entry point function (cyg_addrword_t) & display_thread_info, // entry data "DISPLAY THREAD", // optional thread name display_stack, // stack base MYTHREAD_STACK_SIZE, // stack size, &display_handle, // returned thread handle &display_thread // put thread here ); #else // create display hardware thread diag_printf("display_hw..."); fill_sem_array(sem_array_display, &display_thread_info); rthread_attr_init(&display_hwthread_attr); rthread_attr_setslotnum(&display_hwthread_attr, 0); rthread_attr_setresources(&display_hwthread_attr, sem_array_display, 8); reconos_hwthread_create(16, // scheduling info (eg pri) &display_hwthread_attr, // hw thread attributes shm_init(&display_thread_info), // init data "DISPLAY_THREAD (HW)", // optional thread name display_stack, // stack base MYTHREAD_STACK_SIZE, // stack size, &display_handle, // returned thread handle &display_hwthread, // put thread here (void *) XPAR_PLB_RECONOS_SLOT_1_BASEADDR, XPAR_OPB_INTC_0_PLB_RECONOS_SLOT_1_INTERRUPT_INTR + 1, // associated interrupt vector shm_init(&display_thread_info), SHM_SIZE, sem_array, 8); #endif diag_printf("\nStarting threads...\n"); cyg_thread_resume(input_handle); cyg_thread_resume(laplace_handle); cyg_thread_resume(display_handle); diag_printf("end of main()\n"); }