Exemplo n.º 1
0
int rt_print_init(size_t buffer_size, const char *buffer_name)
{
	struct print_buffer *buffer = pthread_getspecific(buffer_key);
	size_t size = buffer_size;
	unsigned long old_bitmap;
	unsigned j;

	if (!size)
		size = __cobalt_print_bufsz;
	else if (size < RT_PRINT_LINE_BREAK)
		return EINVAL;

	if (buffer) {
		/* Only set name if buffer size is unchanged or default */
		if (size == buffer->size || !buffer_size) {
			set_buffer_name(buffer, buffer_name);
			return 0;
		}
		cleanup_buffer(buffer);
		buffer = NULL;
	}

	/* Find a free buffer in the pool */
	do {
		unsigned long bitmap;
		unsigned i;

		for (i = 0; i < pool_bitmap_len; i++) {
			old_bitmap = atomic_long_read(&pool_bitmap[i]);
			if (old_bitmap)
				goto acquire;
		}

		goto not_found;

	  acquire:
		do {
			bitmap = old_bitmap;
			j = __builtin_ffsl(bitmap) - 1;
			old_bitmap = atomic_long_cmpxchg(&pool_bitmap[i],
							 bitmap,
							 bitmap & ~(1UL << j));
		} while (old_bitmap != bitmap && old_bitmap);
		j += i * __WORDSIZE;
	} while (!old_bitmap);

	buffer = (struct print_buffer *)(pool_start + j * pool_buf_size);

  not_found:

	if (!buffer) {
		assert_nrt();

		buffer = malloc(sizeof(*buffer));
		if (!buffer)
			return ENOMEM;

		buffer->ring = malloc(size);
		if (!buffer->ring)
			return ENOMEM;

		rt_print_init_inner(buffer, size);
	}

	set_buffer_name(buffer, buffer_name);

	pthread_setspecific(buffer_key, buffer);

	return 0;
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
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);
}