static void forked_child_init(void) { struct print_buffer *my_buffer = pthread_getspecific(buffer_key); struct print_buffer **pbuffer = &first_buffer; if (my_buffer) { /* Any content of my_buffer should be printed by our parent, not us. */ memset(my_buffer->ring, 0, my_buffer->size); my_buffer->read_pos = 0; my_buffer->write_pos = 0; } /* re-init to avoid finding it locked by some parent thread */ pthread_mutex_init(&buffer_lock, NULL); while (*pbuffer) { if (*pbuffer == my_buffer) pbuffer = &(*pbuffer)->next; else if ((unsigned long)*pbuffer - pool_start < pool_len) { cleanup_buffer(*pbuffer); pbuffer = &(*pbuffer)->next; } else cleanup_buffer(*pbuffer); } spawn_printer_thread(); }
void cobalt_print_init(void) { const char *value_str; unsigned long long period; first_buffer = NULL; seq_no = 0; value_str = getenv(RT_PRINT_BUFFER_ENV); if (value_str) { errno = 0; __cobalt_print_bufsz = strtol(value_str, NULL, 10); if (errno || __cobalt_print_bufsz < RT_PRINT_LINE_BREAK) { report_error("invalid %s", RT_PRINT_BUFFER_ENV); exit(1); } } period = RT_PRINT_DEFAULT_PERIOD; value_str = getenv(RT_PRINT_PERIOD_ENV); if (value_str) { errno = 0; period = strtoll(value_str, NULL, 10); if (errno) { report_error("invalid %s", RT_PRINT_BUFFER_ENV); exit(1); } } print_period.tv_sec = period / 1000; print_period.tv_nsec = (period % 1000) * 1000000; /* Fill the buffer pool */ { unsigned buffers_count, i; buffers_count = RT_PRINT_DEFAULT_BUFFERS_COUNT; value_str = getenv(RT_PRINT_BUFFERS_COUNT_ENV); if (value_str) { errno = 0; buffers_count = strtoul(value_str, NULL, 0); if (errno) { report_error("invalid %s", RT_PRINT_BUFFERS_COUNT_ENV); exit(1); } } pool_bitmap_len = (buffers_count + __WORDSIZE - 1) / __WORDSIZE; if (!pool_bitmap_len) goto done; pool_bitmap = malloc(pool_bitmap_len * sizeof(*pool_bitmap)); if (!pool_bitmap) { report_error("error allocating rt_printf buffers"); exit(1); } pool_buf_size = sizeof(struct print_buffer) + __cobalt_print_bufsz; pool_len = buffers_count * pool_buf_size; pool_start = (unsigned long)malloc(pool_len); if (!pool_start) { report_error("error allocating rt_printf buffers"); exit(1); } for (i = 0; i < buffers_count / __WORDSIZE; i++) atomic_long_set(&pool_bitmap[i], ~0UL); if (buffers_count % __WORDSIZE) atomic_long_set(&pool_bitmap[i], (1UL << (buffers_count % __WORDSIZE)) - 1); for (i = 0; i < buffers_count; i++) { struct print_buffer *buffer = (struct print_buffer *) (pool_start + i * pool_buf_size); buffer->ring = (char *)(buffer + 1); rt_print_init_inner(buffer, __cobalt_print_bufsz); } } done: pthread_mutex_init(&buffer_lock, NULL); pthread_key_create(&buffer_key, (void (*)(void*))cleanup_buffer); pthread_cond_init(&printer_wakeup, NULL); spawn_printer_thread(); pthread_atfork(NULL, NULL, forked_child_init); rt_print_auto_init(1); }
static __attribute__ ((constructor)) void __rt_print_init(void) { const char *value_str; unsigned long long period; first_buffer = NULL; seq_no = 0; auto_init = 0; default_buffer_size = RT_PRINT_DEFAULT_BUFFER; value_str = getenv(RT_PRINT_BUFFER_ENV); if (value_str) { errno = 0; default_buffer_size = strtol(value_str, NULL, 10); if (errno || default_buffer_size < RT_PRINT_LINE_BREAK) { fprintf(stderr, "Invalid %s\n", RT_PRINT_BUFFER_ENV); exit(1); } } period = RT_PRINT_DEFAULT_PERIOD; value_str = getenv(RT_PRINT_PERIOD_ENV); if (value_str) { errno = 0; period = strtoll(value_str, NULL, 10); if (errno) { fprintf(stderr, "Invalid %s\n", RT_PRINT_PERIOD_ENV); exit(1); } } print_period.tv_sec = period / 1000; print_period.tv_nsec = (period % 1000) * 1000000; #ifdef CONFIG_XENO_FASTSYNCH /* Fill the buffer pool */ { unsigned buffers_count, i; buffers_count = RT_PRINT_DEFAULT_BUFFERS_COUNT; value_str = getenv(RT_PRINT_BUFFERS_COUNT_ENV); if (value_str) { errno = 0; buffers_count = strtoul(value_str, NULL, 0); if (errno) { fprintf(stderr, "Invalid %s\n", RT_PRINT_BUFFERS_COUNT_ENV); exit(1); } } pool_bitmap_len = (buffers_count + BITS_PER_LONG - 1) / BITS_PER_LONG; if (!pool_bitmap_len) goto done; pool_bitmap = malloc(pool_bitmap_len * sizeof(*pool_bitmap)); if (!pool_bitmap) { fprintf(stderr, "Error allocating rt_printf " "buffers\n"); exit(1); } pool_buf_size = sizeof(struct print_buffer) + default_buffer_size; pool_len = buffers_count * pool_buf_size; pool_start = (unsigned long)malloc(pool_len); if (!pool_start) { fprintf(stderr, "Error allocating rt_printf " "buffers\n"); exit(1); } for (i = 0; i < buffers_count / BITS_PER_LONG; i++) xnarch_atomic_set(&pool_bitmap[i], ~0UL); if (buffers_count % BITS_PER_LONG) xnarch_atomic_set(&pool_bitmap[i], (1UL << (buffers_count % BITS_PER_LONG)) - 1); for (i = 0; i < buffers_count; i++) { struct print_buffer *buffer = (struct print_buffer *) (pool_start + i * pool_buf_size); buffer->ring = (char *)(buffer + 1); rt_print_init_inner(buffer, default_buffer_size); } } done: #endif /* CONFIG_XENO_FASTSYNCH */ pthread_mutex_init(&buffer_lock, NULL); pthread_key_create(&buffer_key, (void (*)(void*))cleanup_buffer); pthread_cond_init(&printer_wakeup, NULL); spawn_printer_thread(); pthread_atfork(NULL, NULL, forked_child_init); }