int test_get_by_name(struct harness_t *harness_p) { BTASSERT(thrd_get_by_name("main") == thrd_self()); BTASSERT(thrd_get_by_name("none") == NULL); return (0); }
int test_log_mask(struct harness_t *harness_p) { struct log_object_t foo; /* Initialize the log objects. */ BTASSERT(log_object_init(&foo, "foo", LOG_UPTO(INFO)) == 0); BTASSERT(log_object_get_log_mask(&foo) == 0x0f); /* Log all. */ BTASSERT(log_object_set_log_mask(&foo, LOG_ALL) == 0); BTASSERT(log_object_get_log_mask(&foo) == 0x1f); /* Log none. */ BTASSERT(log_object_set_log_mask(&foo, LOG_NONE) == 0); BTASSERT(log_object_get_log_mask(&foo) == 0x00); /* Log error. */ BTASSERT(log_object_set_log_mask(&foo, LOG_MASK(ERROR)) == 0); BTASSERT(log_object_get_log_mask(&foo) == 0x02); /* Invalid levels are discarded. */ BTASSERT(log_object_set_log_mask(&foo, 0xf0) == 0); BTASSERT(log_object_get_log_mask(&foo) == 0x10); /* Is enabled for. */ BTASSERT(log_object_set_log_mask(&foo, LOG_MASK(ERROR)) == 0); BTASSERT(log_object_is_enabled_for(&foo, LOG_INFO) == 0); BTASSERT(log_object_is_enabled_for(&foo, LOG_ERROR) == 1); thrd_set_log_mask(thrd_self(), 0x00); BTASSERT(log_object_is_enabled_for(NULL, LOG_ERROR) == 0); return (0); }
int test_log_mask(struct harness_t *harness_p) { char command[64]; BTASSERT(thrd_get_log_mask() == 0x0f); BTASSERT(thrd_set_log_mask(thrd_self(), 0x00) == 0x0f); BTASSERT(thrd_get_log_mask() == 0x00); strcpy(command, "/kernel/thrd/set_log_mask main 0xff"); BTASSERT(fs_call(command, NULL, sys_get_stdout(), NULL) == 0); BTASSERT(thrd_get_log_mask() == 0xff); /* Invalid arguments. */ strcpy(command, "/kernel/thrd/set_log_mask"); BTASSERT(fs_call(command, NULL, sys_get_stdout(), NULL) == -EINVAL); BTASSERT(thrd_get_log_mask() == 0xff); strcpy(command, "/kernel/thrd/set_log_mask foo bar"); BTASSERT(fs_call(command, NULL, sys_get_stdout(), NULL) == -ESRCH); BTASSERT(thrd_get_log_mask() == 0xff); strcpy(command, "/kernel/thrd/set_log_mask main foo"); BTASSERT(fs_call(command, NULL, sys_get_stdout(), NULL) == -EINVAL); BTASSERT(thrd_get_log_mask() == 0xff); return (0); }
ssize_t event_read(struct event_t *self_p, void *buf_p, size_t size) { ASSERTN(self_p != NULL, EINVAL); ASSERTN(buf_p != NULL, EINVAL); ASSERTN(size == sizeof(uint32_t), EINVAL); uint32_t *mask_p, mask; mask_p = (uint32_t *)buf_p; sys_lock(); mask = (self_p->mask & *mask_p); /* Event already set? Otherwise wait for it. */ if (mask != 0) { *mask_p = mask; } else { self_p->base.reader_p = thrd_self(); thrd_suspend_isr(NULL); *mask_p = (self_p->mask & *mask_p); } /* Remove read events from the event channel. */ self_p->mask &= (~(*mask_p)); sys_unlock(); return (size); }
static int test_init(struct harness_t *harness_p) { struct thrd_t *thrd_p; int port = REMOTE_HOST_PORT; char remote_host_ip[] = STRINGIFY(REMOTE_HOST_IP); struct inet_addr_t remote_host_address; self_p = thrd_self(); std_printf(FSTR("Connecting to '%s:%d'.\r\n"), remote_host_ip, port); BTASSERT(inet_aton(remote_host_ip, &remote_host_address.ip) == 0); remote_host_address.port = port; BTASSERT(socket_open_tcp(&server_sock) == 0); BTASSERT(socket_connect(&server_sock, &remote_host_address) == 0); BTASSERT(mqtt_client_init(&client, "mqtt_client", NULL, &server_sock, &server_sock, on_publish, NULL) == 0); thrd_p = thrd_spawn(mqtt_client_main, &client, 0, stack, sizeof(stack)); thrd_set_log_mask(thrd_p, LOG_UPTO(DEBUG)); return (0); }
int test_priority(struct harness_t *harness_p) { BTASSERT(thrd_get_prio() == 0); BTASSERT(thrd_set_prio(thrd_self(), 1) == 0); BTASSERT(thrd_get_prio() == 1); return (0); }
int test_prio_list(struct harness_t *harness_p) { struct thrd_prio_list_t list; struct thrd_prio_list_elem_t elems[2]; BTASSERT(thrd_prio_list_init(&list) == 0); elems[0].thrd_p = thrd_self(); elems[1].thrd_p = thrd_self(); thrd_prio_list_push_isr(&list, &elems[0]); thrd_prio_list_push_isr(&list, &elems[1]); BTASSERT(thrd_prio_list_pop_isr(&list) == &elems[0]); BTASSERT(thrd_prio_list_pop_isr(&list) == &elems[1]); return (0); }
/** * Call given callback from the LwIP thread. */ static int tcpip_call_output(struct socket_t *self_p, void (*callback)(void *ctx_p), void *args_p) { self_p->output.cb.args_p = args_p; self_p->output.cb.thrd_p = thrd_self(); tcpip_callback_with_block(callback, self_p, 0); return (thrd_suspend(NULL)); }
int test_stack_top_bottom(struct harness_t *harness_p) { const void *top_p; const void *bottom_p; top_p = thrd_get_top_of_stack(thrd_self()); bottom_p = thrd_get_bottom_of_stack(thrd_self()); std_printf(FSTR("top: 0x%x, bottom: 0x%x, size: %d\r\n"), (int)(intptr_t)top_p, (int)(intptr_t)bottom_p, (int)((intptr_t)top_p - (intptr_t)bottom_p)); #if defined(ARCH_LINUX) BTASSERT(top_p == NULL); BTASSERT(bottom_p != NULL); #else BTASSERT(top_p != NULL); BTASSERT(bottom_p != NULL); BTASSERT(top_p >= bottom_p); #endif return (0); }
int test_suspend_resume(struct harness_t *harness_p) { int err; struct thrd_t *thrd_p; thrd_p = thrd_spawn(suspend_resume_main, thrd_self(), 10, suspend_resume_stack, sizeof(suspend_resume_stack)); err = thrd_suspend(NULL); BTASSERT(err == 3); /* Wait for the spawned thread to terminate, twice. */ BTASSERT(thrd_join(thrd_p) == 0); BTASSERT(thrd_join(thrd_p) == 0); return (0); }
ssize_t queue_write(struct queue_t *self_p, const void *buf_p, size_t size) { ASSERTN(self_p != NULL, EINVAL); ASSERTN(buf_p != NULL, EINVAL); ASSERTN(size > 0, EINVAL); ssize_t res; size_t left; const char *cbuf_p; left = size; cbuf_p = buf_p; sys_lock(); res = queue_write_isr(self_p, cbuf_p, size); if (res >= 0) { left -= res; /* The reader reads the remaining data. */ if (left > 0) { cbuf_p += (size - left); self_p->base.writer_p = thrd_self(); self_p->buf_p = (void *)cbuf_p; self_p->size = size; self_p->left = left; res = thrd_suspend_isr(NULL); } } sys_unlock(); return (res); }
ssize_t queue_read(struct queue_t *self_p, void *buf_p, size_t size) { ASSERTN(self_p != NULL, EINVAL); ASSERTN(buf_p != NULL, EINVAL); ASSERTN(size > 0, EINVAL); size_t left, n, buffer_used_until_end, buffer_used; char *cbuf_p; left = size; cbuf_p = buf_p; sys_lock(); /* Copy data from queue buffer. */ if (self_p->buffer.begin_p != NULL) { buffer_used = get_buffer_used(&self_p->buffer); /* Number of bytes to read from the buffer. */ if (left < buffer_used) { n = left; } else { n = buffer_used; } buffer_used_until_end = BUFFER_USED_UNTIL_END(&self_p->buffer); if (n <= buffer_used_until_end) { /* Read one chunk. */ memcpy(cbuf_p, self_p->buffer.read_p, n); self_p->buffer.read_p += n; } else { /* Read two chunks, to end and then from beginning. */ memcpy(cbuf_p, self_p->buffer.read_p, buffer_used_until_end); memcpy(cbuf_p + buffer_used_until_end, self_p->buffer.begin_p, (n - buffer_used_until_end)); self_p->buffer.read_p = self_p->buffer.begin_p; self_p->buffer.read_p += (n - buffer_used_until_end); } cbuf_p += n; left -= n; } /* Copy data from the writer, if one is present. */ if (self_p->base.writer_p != NULL) { if (left < self_p->left) { n = left; } else { n = self_p->left; } memcpy(cbuf_p, self_p->buf_p, n); self_p->buf_p += n; self_p->left -= n; cbuf_p += n; left -= n; /* Writer buffer empty. */ if (self_p->left == 0) { /* Wake the writer. */ thrd_resume_isr(self_p->base.writer_p, self_p->size); self_p->base.writer_p = NULL; } } /* Suspend this thread if more data should be read. */ if (left > 0) { /* No more data will be written to a stopped queue. */ if (self_p->state == QUEUE_STATE_STOPPED) { size = (size - left); } else { /* The writer writes the remaining data to the reader buffer. */ self_p->base.reader_p = thrd_self(); self_p->buf_p = cbuf_p; self_p->size = size; self_p->left = left; size = thrd_suspend_isr(NULL); } } sys_unlock(); return (size); }
static mp_obj_t module_thrd_self(void) { return (mp_obj_new_int((uintptr_t)thrd_self())); }