Exemple #1
0
void
qb_atomic_int_add(volatile int32_t QB_GNUC_MAY_ALIAS * atomic, int32_t val)
{
	qb_thread_lock(qb_atomic_mutex);
	*atomic += val;
	qb_thread_unlock(qb_atomic_mutex);
}
Exemple #2
0
void
qb_log_thread_stop(void)
{
	int res;
	int value;
	struct qb_log_record *rec;

	if (wthread_active == QB_FALSE && logt_wthread_lock == NULL) {
		return;
	}
	if (wthread_active == QB_FALSE) {
		for (;;) {
			res = sem_getvalue(&logt_print_finished, &value);
			if (res != 0 || value == 0) {
				break;
			}
			sem_wait(&logt_print_finished);

			(void)qb_thread_lock(logt_wthread_lock);

			rec = qb_list_first_entry(&logt_print_finished_records,
					    struct qb_log_record, list);
			qb_list_del(&rec->list);
			logt_memory_used = logt_memory_used -
					   strlen(rec->buffer) -
					   sizeof(struct qb_log_record) - 1;
			(void)qb_thread_unlock(logt_wthread_lock);

			qb_log_thread_log_write(rec->cs, rec->timestamp,
						rec->buffer);
			free(rec->buffer);
			free(rec);
		}
	} else {
Exemple #3
0
static void *
qb_logt_worker_thread(void *data)
{
	struct qb_log_record *rec;
	int dropped = 0;
	int res;

	/*
	 * Signal wthread_create that the initialization process may continue
	 */
	sem_post(&logt_thread_start);
	for (;;) {
retry_sem_wait:
		res = sem_wait(&logt_print_finished);
		if (res == -1 && errno == EINTR) {
			goto retry_sem_wait;
		} else if (res == -1) {
			/*
			 * This case shouldn't happen
			 */
			pthread_exit(NULL);
		}

		(void)qb_thread_lock(logt_wthread_lock);
		if (wthread_should_exit) {
			int value = -1;

			(void)sem_getvalue(&logt_print_finished, &value);
			if (value == 0) {
				(void)qb_thread_unlock(logt_wthread_lock);
				pthread_exit(NULL);
			}
		}

		rec =
		    qb_list_first_entry(&logt_print_finished_records,
				  struct qb_log_record, list);
		qb_list_del(&rec->list);
		logt_memory_used = logt_memory_used - strlen(rec->buffer) -
		    sizeof(struct qb_log_record) - 1;
		dropped = logt_dropped_messages;
		logt_dropped_messages = 0;
		(void)qb_thread_unlock(logt_wthread_lock);
		if (dropped) {
			printf("%d messages lost\n", dropped);
		}

		qb_log_thread_log_write(rec->cs, rec->timestamp, rec->buffer);
		free(rec->buffer);
		free(rec);
	}
}
Exemple #4
0
int32_t
qb_atomic_int_exchange_and_add(volatile int32_t QB_GNUC_MAY_ALIAS * atomic,
			       int32_t val)
{
	int32_t result;

	qb_thread_lock(qb_atomic_mutex);
	result = *atomic;
	*atomic += val;
	qb_thread_unlock(qb_atomic_mutex);

	return result;
}
Exemple #5
0
void
qb_log_thread_log_post(struct qb_log_callsite *cs,
		       time_t timestamp, const char *buffer)
{
	struct qb_log_record *rec;
	size_t buf_size;
	size_t total_size;

	rec = malloc(sizeof(struct qb_log_record));
	if (rec == NULL) {
		return;
	}

	buf_size = strlen(buffer) + 1;
	total_size = sizeof(struct qb_log_record) + buf_size;

	rec->cs = cs;
	rec->buffer = malloc(buf_size);
	if (rec->buffer == NULL) {
		goto free_record;
	}
	memcpy(rec->buffer, buffer, buf_size);

	rec->timestamp = timestamp;

	qb_list_init(&rec->list);
	(void)qb_thread_lock(logt_wthread_lock);
	logt_memory_used += total_size;
	if (logt_memory_used > 512000) {
		free(rec->buffer);
		free(rec);
		logt_memory_used = logt_memory_used - total_size;
		logt_dropped_messages += 1;
		(void)qb_thread_unlock(logt_wthread_lock);
		return;

	} else {
		qb_list_add_tail(&rec->list, &logt_print_finished_records);
	}
	(void)qb_thread_unlock(logt_wthread_lock);

	sem_post(&logt_print_finished);
	return;

free_record:
	free(rec);
}
Exemple #6
0
int32_t
qb_atomic_int_compare_and_exchange(volatile int32_t QB_GNUC_MAY_ALIAS * atomic,
				   int32_t oldval, int32_t newval)
{
	int32_t result;

	qb_thread_lock(qb_atomic_mutex);
	if (*atomic == oldval) {
		result = QB_TRUE;
		*atomic = newval;
	} else {
		result = QB_FALSE;
	}
	qb_thread_unlock(qb_atomic_mutex);

	return result;
}
Exemple #7
0
struct qb_log_callsite *
qb_log_dcs_get(int32_t * newly_created,
	       const char *function,
	       const char *filename,
	       const char *format,
	       uint8_t priority, uint32_t lineno, uint32_t tags)
{
	int32_t rc;
	struct qb_log_callsite *cs = NULL;
	struct callsite_list *csl_head;
	struct callsite_list *csl_last = NULL;
	struct callsite_list *csl;
	const char *safe_filename = filename;
	const char *safe_function = function;
	const char *safe_format = format;

	if (filename == NULL) {
		safe_filename = "";
	}
	if (function == NULL) {
		safe_function = "";
	}
	if (format == NULL) {
		safe_format = "";
	}
	/*
	 * try the fastest access first (no locking needed)
	 */
	rc = qb_array_index(lookup_arr, lineno, (void **)&csl_head);
	assert(rc == 0);
	if (csl_head->cs &&
		priority == csl_head->cs->priority &&
		strcmp(safe_filename, csl_head->cs->filename) == 0 &&
		strcmp(safe_format, csl_head->cs->format) == 0) {
		return csl_head->cs;
	}
	/*
	 * so we will either have to create it or go through a list, so lock it.
	 */
	(void)qb_thread_lock(arr_next_lock);
	if (csl_head->cs == NULL) {
		csl_head->cs = _log_dcs_new_cs(safe_function, safe_filename, safe_format,
					       priority, lineno, tags);
		cs = csl_head->cs;
		csl_head->next = NULL;
		*newly_created = QB_TRUE;
	} else {
		for (csl = csl_head; csl; csl = csl->next) {
			assert(csl->cs->lineno == lineno);
			if (priority == csl->cs->priority &&
			    strcmp(safe_format, csl->cs->format) == 0 &&
			    strcmp(safe_filename, csl->cs->filename) == 0) {
				cs = csl->cs;
				break;
			}
			csl_last = csl;
		}

		if (cs == NULL) {
			csl = calloc(1, sizeof(struct callsite_list));
			if (csl == NULL) {
				goto cleanup;
			}
			csl->cs = _log_dcs_new_cs(safe_function, safe_filename, safe_format,
						  priority, lineno, tags);
			csl->next = NULL;
			csl_last->next = csl;
			cs = csl->cs;
			*newly_created = QB_TRUE;
		}
	}
cleanup:
	(void)qb_thread_unlock(arr_next_lock);

	return cs;
}