Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'master' of dirus.poelzi.uni.cx:Projects/ulatency/trunk …

…into mt

Conflicts:
	src/core.c
  • Loading branch information...
commit e7ec32c0e96a035b3bca87624e1b900184b19844 2 parents 49c3e37 + 954da23
@poelzi authored
View
76 src/core.c
@@ -30,7 +30,6 @@
#include <fcntl.h>
#include <glib.h>
#include <stdio.h>
-#include <sys/mman.h>
#include <sys/types.h>
#include <dlfcn.h>
#include <fnmatch.h>
@@ -66,6 +65,8 @@ struct u_timer timer_filter;
struct u_timer timer_scheduler;
struct u_timer timer_parse;
+GStaticRWLock process_lock = G_STATIC_RW_LOCK_INIT;
+GStaticRWLock delay_lock = G_STATIC_RW_LOCK_INIT;
// delay new processes
@@ -155,6 +156,7 @@ static void u_proc_remove_child_nodes(u_proc *proc) {
static void remove_proc_from_delay_stack(pid_t pid) {
int i = 0;
struct delay_proc *cur;
+ g_static_rw_lock_writer_lock (&delay_lock);
for(i = 0; i < delay_stack->len;) {
cur = g_ptr_array_index(delay_stack, i);
@@ -165,6 +167,8 @@ static void remove_proc_from_delay_stack(pid_t pid) {
i++;
}
}
+ g_static_rw_lock_writer_unlock (&delay_lock);
+
}
/**
@@ -375,7 +379,7 @@ int u_proc_ensure(u_proc *proc, enum ENSURE_WHAT what, int update) {
proc->cmdline_match = g_string_free(match, FALSE);
// empty command line, for kernel threads for example
if(!proc->cmdline->len)
- return FALSE;
+ return TRUE;
if(proc->cmdfile) {
g_free(proc->cmdfile);
proc->cmdfile = NULL;
@@ -414,9 +418,6 @@ int u_proc_ensure(u_proc *proc, enum ENSURE_WHAT what, int update) {
out -= 10;
}
proc->exe = g_strndup((char *)&buf, out);
- } else {
- g_free(path);
- return FALSE;
}
g_free(path);
}
@@ -540,6 +541,7 @@ static inline u_proc *parent_proc_by_pid(pid_t parent_pid, u_proc *child) {
// this should't happen, but under fork stress init may not have
// collected so the parent does not exist, or the parent just died. we try updating
// the process first and try again.
+ g_static_rw_lock_reader_lock (&process_lock);
if(!parent) {
g_debug("parent missing: %d, force update", parent_pid);
if(!find_parent_caller_stack(updates, child->pid)) {
@@ -566,6 +568,8 @@ static inline u_proc *parent_proc_by_pid(pid_t parent_pid, u_proc *child) {
g_warning("pid: %d parent %d missing. attaching to pid 1", child->pid, parent_pid);
return proc_by_pid(1);
}
+ INC_REF(parent);
+ g_static_rw_lock_reader_unlock (&process_lock);
return parent;
}
@@ -583,6 +587,8 @@ static void rebuild_tree() {
gpointer key, value;
u_proc *proc, *parent;
+ g_static_rw_lock_writer_lock (&process_lock);
+
// clear root node
g_node_destroy(processes_tree);
processes_tree = g_node_new(NULL);
@@ -625,6 +631,8 @@ static void rebuild_tree() {
}
g_list_free(keys);
+ g_static_rw_lock_writer_unlock (&process_lock);
+
}
/**
@@ -676,7 +684,13 @@ static gboolean processes_is_last_changed(gpointer key, gpointer value,
* @return boolean if the process got removed
*/
int process_remove(u_proc *proc) {
- return g_hash_table_remove(processes, GUINT_TO_POINTER(proc->pid));
+ int rv;
+
+ g_static_rw_lock_writer_lock (&process_lock);
+ rv = g_hash_table_remove(processes, GUINT_TO_POINTER(proc->pid));
+ g_static_rw_lock_writer_unlock (&process_lock);
+
+ return rv;
}
/**
@@ -688,7 +702,13 @@ int process_remove(u_proc *proc) {
* @return boolean if the process got removed
*/
int process_remove_by_pid(pid_t pid) {
- return g_hash_table_remove(processes, GUINT_TO_POINTER(pid));
+ int rv;
+
+ g_static_rw_lock_writer_lock (&process_lock);
+ rv = g_hash_table_remove(processes, GUINT_TO_POINTER(pid));
+ g_static_rw_lock_writer_unlock (&process_lock);
+
+ return rv;
}
/**
@@ -703,12 +723,16 @@ static void clear_process_changed() {
gpointer ikey, value;
u_proc *proc;
+ g_static_rw_lock_reader_lock (&process_lock);
+
g_hash_table_iter_init (&iter, processes);
while (g_hash_table_iter_next (&iter, &ikey, &value))
{
proc = (u_proc *)value;
proc->changed = FALSE;
}
+ g_static_rw_lock_reader_unlock (&process_lock);
+
return;
}
@@ -821,7 +845,9 @@ int update_processes_run(PROCTAB *proctab, int full) {
freeproc_light(&(proc->proc));
} else {
proc = u_proc_new(&buf);
+ g_static_rw_lock_writer_lock (&process_lock);
g_hash_table_insert(processes, GUINT_TO_POINTER(proc->pid), proc);
+ g_static_rw_lock_writer_unlock (&process_lock);
// we save the origin of cgroups for scheduler constrains
}
// must still have the process allocated
@@ -863,12 +889,14 @@ int update_processes_run(PROCTAB *proctab, int full) {
u_flag_clear_timeout(proc, timeout);
updated = g_list_append(updated, proc);
+ DEC_REF(proc);
+
rv++;
memset(&buf, 0, sizeof(proc_t));
//g_list_foreach(filter_list, filter_run_for_proc, &buf);
//freesupgrp(&buf);
}
-
+ g_static_rw_lock_writer_lock (&process_lock);
// we update the parent links after all processes are updated
for(i = 0; i < rv; i++) {
proc = g_list_nth_data(updated, i);
@@ -896,14 +924,18 @@ int update_processes_run(PROCTAB *proctab, int full) {
}
}
}
+ g_static_rw_lock_writer_unlock (&process_lock);
+
// remove old processes
g_list_free(updated);
if(full) {
+ g_static_rw_lock_writer_lock (&process_lock);
g_hash_table_foreach_remove(processes,
- processes_is_last_changed,
- &run);
+ processes_is_last_changed,
+ &run);
+ g_static_rw_lock_writer_unlock (&process_lock);
// we can completly clean the delay stack as all processes are now processed
// missing so will cause scheduling for dead processes
if(delay_stack->len)
@@ -968,6 +1000,8 @@ static int run_new_pid(gpointer ign) {
if(!delay_stack->len)
return TRUE;
+ g_static_rw_lock_reader_lock (&delay_lock);
+
targets = g_array_new(TRUE, FALSE, sizeof(pid_t));
for(i = 0; i < delay_stack->len;i++) {
@@ -981,15 +1015,22 @@ static int run_new_pid(gpointer ign) {
cur->proc->changed = TRUE;
}
}
+
+ g_static_rw_lock_reader_unlock (&delay_lock);
+
process_new_list(targets, TRUE, FALSE);
// process_new_list removes the entries it processes from the delay stack
// buf it the process is dead already, they stay here in the list. we make
// sure they are removed.
+ g_static_rw_lock_writer_lock (&delay_lock);
+
for(i=0; i<targets->len; i++) {
remove_proc_from_delay_stack(g_array_index(targets, pid_t, i));
}
+ g_static_rw_lock_writer_lock (&delay_lock);
+
g_array_unref(targets);
return TRUE;
}
@@ -1029,7 +1070,10 @@ gboolean process_new_delay(pid_t pid, pid_t parent) {
// put it into the lists
proc_parent = parent_proc_by_pid(parent, proc);
g_node_append(proc_parent->node, proc->node);
+ g_static_rw_lock_writer_lock (&process_lock);
g_hash_table_insert(processes, GUINT_TO_POINTER(pid), proc);
+ g_static_rw_lock_writer_unlock (&process_lock);
+ DEC_REF(proc_parent);
} else {
if(!process_update_pid(pid))
return FALSE;
@@ -1072,6 +1116,8 @@ gboolean process_new_delay(pid_t pid, pid_t parent) {
scheduler_run_one(proc);
}
}
+ //FIXME
+ //DEC_REF(proc);
return TRUE;
}
@@ -1151,7 +1197,7 @@ int process_new_list(GArray *list, int update, int instant) {
int i, j = 0;
pid_t *pids = (pid_t *)malloc((list->len+1)*sizeof(pid_t));
//int pid_t = malloc(sizeof(pid_t)*(list->len+1));
- for(i = 0; i < list->len; i++) {
+ for(; i < list->len; i++) {
if(update || !proc_by_pid(g_array_index(list,pid_t,i))) {
pids[j] = g_array_index(list,pid_t,i);
j++;
@@ -1306,7 +1352,6 @@ static gint u_flag_match_flag(gconstpointer a, gconstpointer match) {
return -1;
}
-
static int u_flag_match_name(gconstpointer a, gconstpointer name) {
u_flag *flg = (u_flag *)a;
@@ -1348,9 +1393,9 @@ int NAME (u_proc *proc, ARG ) { \
CLEAR_BUILD(u_flag_clear_source, const void *var, g_list_find_custom(proc ? proc->flags : system_flags, var, u_flag_match_source))
-CLEAR_BUILD(u_flag_clear_name, const char *name, g_list_find_custom(proc ? proc->flags : system_flags, name, u_flag_match_name))
+CLEAR_BUILD(u_flag_clear_flag, const void *flag, g_list_find_custom(proc ? proc->flags : system_flags, flag, u_flag_match_flag))
-CLEAR_BUILD(u_flag_clear_flag, const void *var, g_list_find_custom(proc ? proc->flags : system_flags, var, u_flag_match_flag))
+CLEAR_BUILD(u_flag_clear_name, const char *name, g_list_find_custom(proc ? proc->flags : system_flags, name, u_flag_match_name))
CLEAR_BUILD(u_flag_clear_timeout, time_t tm, g_list_find_custom(proc ? proc->flags : system_flags, GUINT_TO_POINTER(tm), u_flag_match_timeout))
@@ -1618,9 +1663,6 @@ int iterate(gpointer rv) {
u_timer_stop_clear(&timer_filter);
u_timer_stop_clear(&timer_scheduler);
- // try the make current memory non swapalbe
- if(mlockall(MCL_CURRENT) && getuid() == 0)
- g_debug("can't mlock memory");
return GPOINTER_TO_INT(rv);
View
24 src/linux_netlink.c
@@ -49,7 +49,8 @@
#define BUFF_SIZE (MAX(MAX(SEND_MESSAGE_SIZE, RECV_MESSAGE_SIZE), 1024))
#define MIN_RECV_SIZE (MIN(SEND_MESSAGE_SIZE, RECV_MESSAGE_SIZE))
-
+static GMainContext *nl_context;
+static GThread *nl_thread;
/**
* Handle a netlink message. In the event of PROC_EVENT_UID or PROC_EVENT_GID,
@@ -80,7 +81,7 @@ static int nl_handle_msg(struct cn_msg *cn_hdr)
ev->event_data.id.r.ruid,
ev->event_data.id.e.euid);
//process_update_pid(ev->event_data.id.process_pid);
- process_new(ev->event_data.id.process_pid, FALSE);
+ process_new_delay(ev->event_data.id.process_pid, 0);
break;
case PROC_EVENT_GID:
u_trace("GID Event: PID = %d, tGID = %d, rGID = %d,"
@@ -89,7 +90,7 @@ static int nl_handle_msg(struct cn_msg *cn_hdr)
ev->event_data.id.r.rgid,
ev->event_data.id.e.egid);
//process_update_pid(ev->event_data.id.process_pid);
- process_new(ev->event_data.id.process_pid, FALSE);
+ process_new_delay(ev->event_data.id.process_pid, 0);
break;
case PROC_EVENT_EXIT:
u_trace("EXIT Event: PID = %d", ev->event_data.exit.process_pid);
@@ -202,6 +203,14 @@ nl_connection_handler (GSocket *socket, GIOCondition condition, gpointer user_da
}
+static gpointer nl_thread_run(gpointer data) {
+ while(TRUE){
+ g_main_context_iteration(nl_context, TRUE);
+ printf("nl iter\n");
+ }
+}
+
+
int init_netlink(GMainLoop *loop) {
GSocket *gsocket = NULL;
int socket_fd = 0;
@@ -274,10 +283,17 @@ int init_netlink(GMainLoop *loop) {
}
g_debug("sent\n");
+ nl_context = g_main_context_new();
+
/* socket has data */
source = g_socket_create_source (gsocket, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, NULL);
g_source_set_callback (source, (GSourceFunc) nl_connection_handler, loop, NULL);
- g_source_attach (source, NULL);
+ g_source_attach (source, nl_context);
+ nl_thread = g_thread_create(nl_thread_run, NULL, FALSE, &error);
+ if(error) {
+ g_warning("can't create nl thread\n");
+ goto out;
+ }
return 0;
out:
View
7 src/lua_binding.c
@@ -898,12 +898,12 @@ static int u_proc_get_oom_score (lua_State *L) {
static int u_proc_ioprio_set (lua_State *L) {
u_proc *proc = check_u_proc(L, 1);
int prio = luaL_checkint(L, 2);
- int class = luaL_checkint(L, 3);
+ int cls = luaL_checkint(L, 3);
if(!U_PROC_HAS_STATE(proc, UPROC_ALIVE))
return 0;
- lua_pushinteger(L, !ioprio_setpid(proc->pid, prio, class));
+ lua_pushinteger(L, !ioprio_setpid(proc->pid, prio, cls));
return 1;
}
@@ -1074,7 +1074,7 @@ static int u_proc_index (lua_State *L)
}
}
- if(!strcmp(key, "is_valid" )) { \
+ if(!strcmp(key, "is_valid" )) {
lua_pushboolean(L, U_PROC_IS_VALID(proc));
return 1;
} else if(!strcmp(key, "is_invalid" )) {
@@ -2314,3 +2314,4 @@ int load_lua_rule_file(lua_State *L, const char *name) {
}
+
View
9 src/ulatency.h
@@ -64,7 +64,7 @@
#define CONFIG_CORE "core"
#define U_HEAD \
- guint ref; \
+ volatile gint ref; \
void (*free_fnk)(void *data);
struct _U_HEAD {
@@ -193,10 +193,10 @@ typedef struct _filter {
void *data;
} u_filter;
-#define INC_REF(P) P ->ref++;
+#define INC_REF(P) g_atomic_int_inc(&P->ref);
#define DEC_REF(P) \
- do { struct _U_HEAD *uh = (struct _U_HEAD *) P ; uh->ref--; g_assert(uh->ref >= 0); \
- if( uh->ref == 0 && uh->free_fnk) { uh->free_fnk( P ); P = NULL; }} while(0);
+ do { struct _U_HEAD *uh = (struct _U_HEAD *) P ; \
+ if( g_atomic_int_dec_and_test(&uh->ref) && uh->free_fnk) { uh->free_fnk( P ); P = NULL; }} while(0);
#define FREE_IF_UNREF(P,FNK) if( P ->ref == 0 ) { FNK ( P ); }
@@ -313,6 +313,7 @@ extern GNode* processes_tree;
extern lua_State *lua_main_state;
extern GList* system_flags;
extern int system_flags_changed;
+extern GStaticRWLock process_lock;
#ifdef ENABLE_DBUS
extern DBusGConnection *U_dbus_connection; // usully the system bus, but may differ on develop mode
extern DBusGConnection *U_dbus_connection_system; // always the system bus
Please sign in to comment.
Something went wrong with that request. Please try again.