Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tests/compile keymap server #539

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,12 @@ if not cc.has_header_symbol('limits.h', 'PATH_MAX', prefix: system_ext_define)
configh_data.set('PATH_MAX', 4096)
endif
endif
if cc.get_argument_syntax() == 'msvc'
add_project_arguments(
cc.get_supported_arguments(['/experimental:c11atomics']),
language: 'c'
)
endif

# Silence some security & deprecation warnings on MSVC
# for some unix/C functions we use.
Expand Down Expand Up @@ -512,6 +518,17 @@ if build_tools
c_args: ['-DENABLE_PRIVATE_APIS'],
include_directories: [include_directories('src', 'include')],
install: false)
thread_dep = dependency('threads', required: false)
if thread_dep.found() and cc.has_header('sys/un.h')
# Similar to previous tool, but for batch processing using a server
executable('compile-keymap-server',
'tools/compile-keymap-server.c',
libxkbcommon_sources,
dependencies: [tools_dep, thread_dep],
c_args: ['-DENABLE_KEYMAP_SOCKET'],
include_directories: [include_directories('src', 'include')],
install: false)
endif

# Tool: compose
executable('xkbcli-compile-compose',
Expand Down
109 changes: 109 additions & 0 deletions src/atom.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@
#include "atom.h"
#include "darray.h"
#include "utils.h"
#ifdef ENABLE_KEYMAP_SOCKET
#include <stdatomic.h>
#endif

/* FNV-1a (http://www.isthe.com/chongo/tech/comp/fnv/). */
static inline uint32_t
Expand All @@ -95,6 +98,7 @@ hash_buf(const char *string, size_t len)
return hash;
}

#ifndef ENABLE_KEYMAP_SOCKET
/*
* The atom table is an insert-only linear probing hash table
* mapping strings to atoms. Another array maps the atoms to
Expand Down Expand Up @@ -191,3 +195,108 @@ atom_intern(struct atom_table *table, const char *string, size_t len, bool add)

assert(!"couldn't find an empty slot during probing");
}

#else

struct atom_table {
size_t size;
_Atomic(char *) *strings;
};

struct atom_table *
atom_table_new(size_t size_log2)
{
struct atom_table *table = calloc(1, sizeof(*table));
if (!table)
return NULL;
size_t size = 1u << size_log2;
table->size = size;
table->strings = calloc(size, sizeof(char*));
return table;
}

void
atom_table_free(struct atom_table *table)
{
if (!table)
return;

size_t count = 0;
for (size_t k = 0 ; k < table->size; k++) {
if (table->strings[k]) {
free(table->strings[k]);
count++;
}
}
free(table->strings);
free(table);
}


xkb_atom_t
atom_intern(struct atom_table *table, const char *string, size_t len, bool add)
{

uint32_t hash = hash_buf(string, len);
char *new_value = NULL;
for (size_t i = 0; i < table->size; i++) {
xkb_atom_t index_pos = (hash + i) & (table->size - 1);
if (index_pos == XKB_ATOM_NONE)
continue;

char *existing_value = atomic_load_explicit(&table->strings[index_pos],
memory_order_acquire);

/* Check if there is a value at the current index */
if (!existing_value) {
/* No value defined. Check if we are allowed to add one */
if (!add)
return XKB_ATOM_NONE;

/*
* Prepare addition: duplicate string.
* Warning: This may not be our first attempt!
*/
if (!new_value)
new_value = strndup(string, len);
if (!new_value) {
/* Failed memory allocation */
// FIXME: error handling?
return XKB_ATOM_NONE;
}
/* Try to register a new entry */
if (atomic_compare_exchange_strong_explicit(
&table->strings[index_pos], &existing_value, new_value,
memory_order_release, memory_order_acquire)) {
return index_pos;
}
/*
* We were not fast enough to take the spot.
* But maybe the newly added value is our value, so read it again.
*/
existing_value = atomic_load_explicit(&table->strings[index_pos],
memory_order_acquire);
}

/* Check the value are equal */
if (strncmp(existing_value, string, len) == 0 &&
existing_value[len] == '\0') {
/* We may have tried unsuccessfully to add the string */
free(new_value);
return index_pos;
}
/* Hash collision: try next atom */
}

free(new_value);
assert(!"couldn't find an empty slot during probing");
}

const char *
atom_text(struct atom_table *table, xkb_atom_t atom)
{
assert(atom < table->size);
return table->strings[atom];
}

#endif
5 changes: 5 additions & 0 deletions src/atom.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,13 @@ typedef uint32_t xkb_atom_t;

struct atom_table;

#ifdef ENABLE_KEYMAP_SOCKET
struct atom_table *
atom_table_new(size_t size);
#else
struct atom_table *
atom_table_new(void);
#endif

void
atom_table_free(struct atom_table *table);
Expand Down
10 changes: 8 additions & 2 deletions src/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdatomic.h>

#include "xkbcommon/xkbcommon.h"
#include "utils.h"
Expand Down Expand Up @@ -189,7 +190,7 @@ xkb_context_include_path_get(struct xkb_context *ctx, unsigned int idx)
XKB_EXPORT struct xkb_context *
xkb_context_ref(struct xkb_context *ctx)
{
ctx->refcnt++;
atomic_fetch_add(&ctx->refcnt, 1);
return ctx;
}

Expand All @@ -200,7 +201,7 @@ xkb_context_ref(struct xkb_context *ctx)
XKB_EXPORT void
xkb_context_unref(struct xkb_context *ctx)
{
if (!ctx || --ctx->refcnt > 0)
if (!ctx || atomic_fetch_sub(&ctx->refcnt, 1) > 1)
return;

free(ctx->x11_atom_cache);
Expand Down Expand Up @@ -312,7 +313,12 @@ xkb_context_new(enum xkb_context_flags flags)
return NULL;
}

#ifdef ENABLE_KEYMAP_SOCKET
/* NOTE: Size should be adusted to deal with xkeyboard-config database */
ctx->atom_table = atom_table_new(14);
#else
ctx->atom_table = atom_table_new();
#endif
if (!ctx->atom_table) {
xkb_context_unref(ctx);
return NULL;
Expand Down
6 changes: 5 additions & 1 deletion src/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,15 @@
#ifndef CONTEXT_H
#define CONTEXT_H

#include <stdatomic.h>

#include "xkbcommon/xkbcommon.h"
#include "atom.h"
#include "messages-codes.h"
#include "src/utils.h"

struct xkb_context {
int refcnt;
atomic_int refcnt;

ATTR_PRINTF(3, 0) void (*log_fn)(struct xkb_context *ctx,
enum xkb_log_level level,
Expand Down
Loading
Loading