#include "fd-handler.h"
#include "proc-common.h"
-static GHashTable *tid_table;
-
-struct cpu_boosting_worker worker;
-bool cpu_boosting_success[CPU_BOOSTING_LEVEL_END] = {false, };
-struct sched_attr cpu_boosting_attr[CPU_BOOSTING_LEVEL_END];
+static GHashTable *tid_table; /* cpu_boosting info per thread (tid, attr, gsource_id) hash table */
+static pthread_mutex_t mutex;
+static struct cpu_boosting_worker worker;
+static struct sched_attr cpu_boosting_attr[CPU_BOOSTING_LEVEL_END];
+static bool cpu_boosting_success[CPU_BOOSTING_LEVEL_END] = {false, };
static void cpu_boosting_destroy_request(struct cpu_boosting_input *input);
} \
} while (0)
+static cpu_boosting_level_e cpu_boosting_level_search(struct sched_attr attr)
+{
+ for (int level = CPU_BOOSTING_LEVEL_STRONG; level < CPU_BOOSTING_LEVEL_END; level++) {
+ if (cpu_boosting_attr[level].sched_policy == SCHED_RR ||
+ cpu_boosting_attr[level].sched_policy == SCHED_FIFO) {
+ if (cpu_boosting_attr[level].sched_priority == attr.sched_priority)
+ return level;
+ }
+ else if (cpu_boosting_attr[level].sched_nice == attr.sched_nice)
+ return level;
+ }
+
+ return CPU_BOOSTING_LEVEL_NONE;
+}
+
+static int cpu_boosting_get_tids(pid_t pid, resource_pid_t *resource_pid)
+{
+ int ret;
+ int tid;
+ DIR *dir;
+ int *tid_list = NULL;
+ int alloc_count = 0;
+ int tid_count = 0;
+ struct dirent *dirent;
+ _cleanup_free_ char *buf = NULL;
+
+ ret = asprintf(&buf, "/proc/%d/task", pid);
+ if (ret < 0) {
+ _E("[CPU-BOOSTING] Failed to allocate buf (dir = %s)", buf);
+ return RESOURCED_ERROR_OUT_OF_MEMORY;
+ }
+
+ dir = opendir(buf);
+ if (!dir) {
+ _E("[CPU-BOOSTING] Failed to open (dir = %s)", buf);
+ return RESOURCED_ERROR_FAIL;
+ }
+
+ while ((dirent = readdir(dir))) {
+ const char *id = dirent->d_name;
+ if(!isdigit(*id))
+ continue;
+
+ tid = atoi(id);
+ if (tid > 0) {
+ if (alloc_count == tid_count) {
+ alloc_count += 15;
+ tid_list = (int *)realloc(tid_list, alloc_count * sizeof(pid_t));
+ if (tid_list == NULL) {
+ _E("[CPU-BOOSTING] Failed to allocate memory");
+ return RESOURCED_ERROR_OUT_OF_MEMORY;
+ }
+ }
+ tid_list[tid_count++] = tid;
+ }
+ else
+ _E("[CPU-BOOSTING] Thread (id = %d) should be larger than 0", tid);
+ }
+ closedir(dir);
+
+ resource_pid->tid = tid_list;
+ resource_pid->tid_count = tid_count;
+
+ return RESOURCED_ERROR_NONE;
+}
+
static void cpu_boosting_destroy_request(struct cpu_boosting_input *input)
{
if (input == NULL)
int byte;
if (sock == 0)
- return; /* cpu_boosting by conf */
+ return;
else if (sock < 0) {
_E("[CPU-BOOSTING] socket cannot be negative");
return;
output->level.tid_count * (unsigned int)sizeof(int), byte);
return;
}
+
+ if (output->level.tid_level)
+ free(output->level.tid_level);
}
else {
/* Send a header */
if (input->client_input.body_size > 0 &&
input->client_input.pid.tid_count > 0) {
int *tid_list;
+ int body_size = input->client_input.body_size;
int tid_count = input->client_input.pid.tid_count;
tid_list = (int *)calloc(tid_count, sizeof(int));
input->client_input.pid.tid = tid_list;
/* Get a body from the client */
- byte = recv(sock, (void *)tid_list, tid_count * sizeof(int), 0);
- if (byte != tid_count * sizeof(int)) {
+ byte = recv(sock, (void *)tid_list, body_size, 0);
+ if (byte != body_size) {
ret = RESOURCED_ERROR_FAIL;
- if (byte == 0)
- goto destroy_input; /* connection is closed */
+ if (byte < 0)
+ _E("[CPU-BOOSTING] error is based on %s", strerror(errno));
+ else if (byte > 0)
+ _E("[CPU-BOOSTING] client input size is %d, but received size is %d",
+ body_size, byte);
- _E("[CPU-BOOSTING] error is based on %s", strerror(errno));
- _E("[CPU-BOOSTING] client input size is %u, but received size is %d",
- tid_count * (unsigned int)sizeof(int), byte);
goto destroy_input;
}
}
-
-/* if (input->client_input.command == CPU_BOOSTING_COMMAND_SET ||
- input->client_input.command == CPU_BOOSTING_COMMAND_CLEAR) {
- output.success = true;
- output.level.tid_level = NULL;
- output.level.tid_count = 0;
- cpu_boosting_send_reply(sock, &output);
- }*/
+ else if (input->client_input.body_size == 0 &&
+ input->client_input.pid.pid > 0) {
+ ret = cpu_boosting_get_tids(input->client_input.pid.pid, &input->client_input.pid);
+ if (ret != RESOURCED_ERROR_NONE)
+ goto destroy_input;
+ }
+ else {
+ _E("[CPU-BOOSTING] Unknown header format");
+ goto destroy_input;
+ }
if (input->client_input.command == CPU_BOOSTING_COMMAND_GET)
input->sock = sock; /* For a reply */
{
assert(data);
+ int ret;
struct proc_status *ps = (struct proc_status *)data;
struct cpu_boosting_input *input;
cpu_boosting_level_e cpu_boosting_level;
return RESOURCED_ERROR_FAIL;
}
- pid.tid = NULL;
- pid.tid_count = 0;
- pid.pid = ps->pid;
- if (pid.pid <= 0) {
+ if (ps->pid <= 0) {
_E("[CPU-BOOSTING] pid should be larger than 0");
return RESOURCED_ERROR_FAIL;
}
+
cpu_boosting_level = ps->pci->cpu_boosting_level;
if (!cpu_boosting_success[cpu_boosting_level]) {
_I("[CPU-BOOSTING] cpu boosting (level = %d) is not supported", cpu_boosting_level);
return RESOURCED_ERROR_NONE;
}
+ ret = cpu_boosting_get_tids(ps->pid, &pid);
+ if (ret != RESOURCED_ERROR_NONE)
+ return ret;
+
input = cpu_boosting_new_request();
if (input == NULL)
return RESOURCED_ERROR_FAIL;
+
CPU_BOOSTING_SET_REQUEST(input, CPU_BOOSTING_COMMAND_SET, cpu_boosting_level, -1, pid);
CPU_BOOSTING_ENQUEUE_REQUEST(input);
static gboolean cpu_boosting_timeout(gpointer data)
{
+ int ret;
struct cpu_boosting_input *input = (struct cpu_boosting_input *)data;
if (input == NULL) {
int tid_count = input->client_input.pid.tid_count;
int *tid_list = input->client_input.pid.tid;
- cpu_boosting_level_e cpu_boosting_level = CPU_BOOSTING_LEVEL_NONE;
for (int i = 0; i < tid_count; i++) {
- guint *gsource_id;
+ if (tid_list[i] > 0) {
+ pthread_mutex_lock(&mutex);
+
+ struct cpu_boosting_info *info = g_hash_table_lookup(tid_table, &tid_list[i]);
+ /*
+ * info is NULL when clearing boosting before timeout
+ * info->gsource_id != *(input->gsource_id) when setting boosting again before timeout
+ */
+ if (info == NULL || info->gsource_id != *(input->gsource_id)) {
+ pthread_mutex_unlock(&mutex);
+ continue;
+ }
- gsource_id = (guint *)g_hash_table_lookup(tid_table, &tid_list[i]);
- if (gsource_id == NULL || *gsource_id != *(input->gsource_id))
- continue;
+ ret = sched_setattr(tid_list[i], &info->origin_attr, 0);
+ g_hash_table_remove(tid_table, &tid_list[i]);
- if (tid_list[i] > 0) {
- sched_setattr(tid_list[i], &cpu_boosting_attr[cpu_boosting_level], 0);
+ pthread_mutex_unlock(&mutex);
+
+ if (ret != RESOURCED_ERROR_NONE)
+ _E("[CPU-BOOSTING] Failed to clear boost cpu of (tid = %d)", tid_list[i]);
}
- else {
+ else
_E("[CPU-BOOSTING] Thread (id = %d) should be larger than 0", tid_list[i]);
- }
}
cpu_boosting_destroy_request(input);
return G_SOURCE_REMOVE;
}
-static void cpu_boosting_set_or_clear(struct cpu_boosting_input *input)
+static struct cpu_boosting_info *cpu_boosting_find_and_insert_attr(pid_t tid)
{
int ret;
- bool need_to_clear = false;
+
+ pthread_mutex_lock(&mutex);
+
+ struct cpu_boosting_info *info = g_hash_table_lookup(tid_table, &tid);
+ if (info == NULL) {
+ pthread_mutex_unlock(&mutex);
+
+ info = (struct cpu_boosting_info *)calloc(1, sizeof (struct cpu_boosting_info));
+ if (info == NULL) {
+ _E("[CPU-BOOSTING] Failed to allocate memory");
+ return NULL;
+ }
+
+ ret = sched_getattr(tid, &info->origin_attr, 0);
+ if (ret != RESOURCED_ERROR_NONE) {
+ free(info);
+ return NULL;
+ }
+ info->tid = tid;
+
+ pthread_mutex_lock(&mutex);
+ g_hash_table_insert(tid_table, &info->tid, info);
+ }
+
+ info->gsource_id = 0;
+ pthread_mutex_unlock(&mutex);
+ return info;
+}
+
+static void cpu_boosting_set_gsource_id(pid_t tid, guint id)
+{
+ struct cpu_boosting_info *info = g_hash_table_lookup(tid_table, &tid);
+ if (info == NULL) {
+ _E("[CPU-BOOSTING] cpu boosting info cannot be NULL");
+ return;
+ }
+
+ info->gsource_id = id;
+}
+
+static void cpu_boosting_set(struct cpu_boosting_input *input)
+{
int fail_cnt = 0;
- int pid = input->client_input.pid.pid;
+ int success_cnt = 0;
+ struct cpu_boosting_info *info;
int tid_count = input->client_input.pid.tid_count;
int *tid_list = input->client_input.pid.tid;
int timeout_msec = input->client_input.timeout_msec;
cpu_boosting_level_e cpu_boosting_level = input->client_input.level;
- if (pid > 0) {
- int tid;
- DIR *dir;
- struct dirent *dirent;
- _cleanup_free_ char *buf = NULL;
- ret = asprintf(&buf, "/proc/%d/task", pid);
- if (ret < 0) {
- fail_cnt++;
- _E("[CPU-BOOSTING] There is no (dir = %s)", buf);
- goto output_update;
+ for (int i = 0; i < tid_count; i++) {
+ if (tid_list[i] > 0) {
+ if ((info = cpu_boosting_find_and_insert_attr(tid_list[i])) == NULL) {
+ fail_cnt++;
+ continue;
+ }
+
+ if (sched_setattr(tid_list[i], &cpu_boosting_attr[cpu_boosting_level], 0) < 0) {
+ _E("[CPU-BOOSTING] Failed to boost cpu of (tid = %d) with (level = %d)",
+ tid_list[i], cpu_boosting_level);
+ fail_cnt++;
+ continue;
+ }
+ success_cnt++;
}
+ else {
+ _E("[CPU-BOOSTING] Thread (id = %d) should be larger than 0", tid_list[i]);
+ }
+ }
- dir = opendir(buf);
- if (!dir) {
- fail_cnt++;
- _E("[CPU-BOOSTING] Failed to open (dir = %s)", buf);
- goto output_update;
+ if (fail_cnt > 0)
+ _E("[CPU-BOOSTING] Boosting success ratio = %d/%d", success_cnt, fail_cnt + success_cnt);
+ else
+ _D("[CPU-BOOSTING] Success CPU boosting");
+
+ /*
+ * If timeout value is larger than 0 and at least one boosting succeed,
+ * then set the timer to restore
+ */
+ if (timeout_msec > 0 && success_cnt > 0) {
+ input->gsource_id = g_new(guint, 1);
+ *(input->gsource_id) = g_timeout_add(timeout_msec, cpu_boosting_timeout, input);
+
+ for (int i = 0; i < tid_count; i++) {
+ if (tid_list[i] > 0)
+ cpu_boosting_set_gsource_id(tid_list[i], *(input->gsource_id));
}
+ }
+ else
+ cpu_boosting_destroy_request(input);
+}
- while ((dirent = readdir(dir))) {
- const char *id = dirent->d_name;
- if(!isdigit(*id))
- continue;
+static void cpu_boosting_clear(struct cpu_boosting_input *input)
+{
+ int ret;
+ int fail_cnt = 0;
+ int success_cnt = 0;
+ int tid_count = input->client_input.pid.tid_count;
+ int *tid_list = input->client_input.pid.tid;
- tid = atoi(id);
- if (tid > 0) {
- g_hash_table_remove(tid_table, (gpointer)&tid);
- if (sched_setattr(tid, &cpu_boosting_attr[cpu_boosting_level], 0) < 0) {
- _E("[CPU-BOOSTING] Failed to boost cpu of (tid = %d) with (level = %d)",
- tid, cpu_boosting_level);
+ for (int i = 0; i < tid_count; i++) {
+ if (tid_list[i] > 0) {
+ pthread_mutex_lock(&mutex);
+
+ struct cpu_boosting_info *info = g_hash_table_lookup(tid_table, &tid_list[i]);
+ if (info == NULL) {
+ pthread_mutex_unlock(&mutex);
+
+ struct sched_attr attr;
+ if (sched_getattr(tid_list[i], &attr, 0) < 0) {
+ _E("[CPU-BOOSTING] Failed to get boost cpu of (tid = %d)", tid_list[i]);
fail_cnt++;
continue;
}
- need_to_clear = true;
- }
- else
- _E("[CPU-BOOSTING] Thread (id = %d) should be larger than 0", tid);
- }
- closedir(dir);
- }
- else {
- for (int i = 0; i < tid_count; i++) {
- if (tid_list[i] > 0) {
- g_hash_table_remove(tid_table, (gpointer)&tid_list[i]);
- if (sched_setattr(tid_list[i], &cpu_boosting_attr[cpu_boosting_level], 0) < 0) {
- _E("[CPU-BOOSTING] Failed to boost cpu of (tid = %d) with (level = %d)",
- tid_list[i], cpu_boosting_level);
+
+ cpu_boosting_level_e level = cpu_boosting_level_search(attr);
+ if (level != CPU_BOOSTING_LEVEL_NONE) {
+ ret = sched_setattr(tid_list[i],
+ &cpu_boosting_attr[CPU_BOOSTING_LEVEL_NONE], 0);
+ if (ret != RESOURCED_ERROR_NONE) {
+ _E("[CPU-BOOSTING] Failed to clear boost cpu of (tid = %d)", tid_list[i]);
+ fail_cnt++;
+ continue;
+ }
+ }
+ else {
+ _E("[CPU-BOOSTING] Try to clear non-boosted process (policy = %d, priority = %d, nice = %d", attr.sched_policy, attr.sched_priority, attr.sched_nice);
fail_cnt++;
continue;
}
- need_to_clear = true;
}
else {
- _E("[CPU-BOOSTING] Thread (id = %d) should be larger than 0", tid_list[i]);
+ ret = sched_setattr(tid_list[i], &info->origin_attr, 0);
+ g_hash_table_remove(tid_table, &tid_list[i]);
+
+ pthread_mutex_unlock(&mutex);
+
+ if (ret != RESOURCED_ERROR_NONE) {
+ _E("[CPU-BOOSTING] Failed to clear boost cpu of (tid = %d)", tid_list[i]);
+ fail_cnt++;
+ continue;
+ }
}
+
+ success_cnt++;
+ }
+ else {
+ _E("[CPU-BOOSTING] Thread (id = %d) should be larger than 0", tid_list[i]);
}
}
-output_update:
if (fail_cnt > 0)
- _E("[CPU-BOOSTING] Boosting fail count = %d", fail_cnt);
+ _E("[CPU-BOOSTING] Boosting success ratio = %d/%d", success_cnt, fail_cnt + success_cnt);
+ else
+ _D("[CPU-BOOSTING] Success CPU boosting clear");
+ cpu_boosting_destroy_request(input);
+}
- /*
- * If timeout value is larger than 0 and at least one boosting is succeed,
- * then set the timer to restore
- */
- if (timeout_msec > 0 && need_to_clear) {
- input->gsource_id = g_new(guint, 1);
- *(input->gsource_id) = g_timeout_add(timeout_msec, cpu_boosting_timeout, input);
+static void cpu_boosting_get(struct cpu_boosting_input *input,
+ cpu_boosting_output_t *output)
+{
+ int fail_cnt = 0;
+ int success_cnt = 0;
+ struct sched_attr attr;
+ int tid_count = input->client_input.pid.tid_count;
+ int *tid_list = input->client_input.pid.tid;
- for (int i = 0; i < tid_count; i++) {
- if (tid_list[i] <= 0)
- continue;
+ output->level.tid_level = (int *)calloc(tid_count, sizeof (int));
+ if (output->level.tid_level == NULL) {
+ _E("[CPU-BOOSTING] Failed to allocate memory");
+ fail_cnt = 1;
+ goto output_update;
+ }
- g_hash_table_insert(tid_table, (gpointer)&tid_list[i],
- (gpointer)input->gsource_id);
+ for (int i = 0; i < tid_count; i++) {
+ if (tid_list[i] > 0) {
+ if (sched_getattr(tid_list[i], &attr, 0) < 0) {
+ _E("[CPU-BOOSTING] Failed to get boost cpu of (tid = %d)", tid_list[i]);
+ fail_cnt++;
+ continue;
+ }
+ output->level.tid_level[success_cnt++] = cpu_boosting_level_search(attr);
+ }
+ else {
+ fail_cnt++;
+ _E("[CPU-BOOSTING] Thread (id = %d) should be larger than 0", tid_list[i]);
}
}
+ output->level.tid_count = success_cnt;
+
+output_update:
+ if (fail_cnt > 0) {
+ _E("[CPU-BOOSTING] Get boosting success ratio = %d/%d", success_cnt, fail_cnt + success_cnt);
+ output->success = false;
+ }
else {
- cpu_boosting_destroy_request(input);
+ _D("[CPU-BOOSTING] Success CPU boosting get");
+ output->success = true;
}
-}
-
-static void cpu_boosting_get(struct cpu_boosting_input *input,
- cpu_boosting_output_t *output)
-{
cpu_boosting_send_reply(input->sock, output);
+ cpu_boosting_destroy_request(input);
}
/* Cpu boosting thread's main code */
*/
switch (input->client_input.command) {
case CPU_BOOSTING_COMMAND_SET:
+ cpu_boosting_set(input);
+ break;
case CPU_BOOSTING_COMMAND_CLEAR:
- cpu_boosting_set_or_clear(input);
+ cpu_boosting_clear(input);
break;
case CPU_BOOSTING_COMMAND_GET:
+ output.level.tid_level = NULL;
+ output.level.tid_count = 0;
cpu_boosting_get(input, &output);
break;
case CPU_BOOSTING_COMMAND_NONE:
pthread_exit(NULL);
}
-static int cpu_boosting_thread_activate(void)
-{
- int ret;
-
- if (CPU_BOOSTING_WORKER_IS_ACTIVE)
- return RESOURCED_ERROR_NONE;
-
- worker.queue = g_async_queue_new_full(cpu_boosting_input_destroy);
- if (!worker.queue) {
- _E("[CPU-BOOSTING] Failed to create request queue");
- return RESOURCED_ERROR_FAIL;
- }
-
- ret = pthread_create(&worker.thread, NULL,
- cpu_boosting_func, NULL);
- if (ret == 0) {
- pthread_detach(worker.thread);
- ret = RESOURCED_ERROR_NONE;
- }
- else {
- _E("[CPU-BOOSTING] Failed to create cpu boosting thread");
- ret = RESOURCED_ERROR_FAIL;
- }
-
- return ret;
-}
-
/* Called by resourced main thread */
static void cpu_boosting_drain_queue(void)
{
g_async_queue_unlock(worker.queue);
}
-/* Called by resourced main thread */
-static void cpu_boosting_thread_deactivate(void)
-{
- if (!CPU_BOOSTING_WORKER_IS_ACTIVE)
- return;
-
- CPU_BOOSTING_WORKER_DEACTIVATE;
- cpu_boosting_drain_queue();
-
- g_async_queue_unref(worker.queue);
-}
-
static int cpu_boosting_init_socket(void)
{
/* Create a server socket */
}
/* Client asks send() to the resourced, so call recv() */
-bool cpu_boosting_recv_from_client(int fd, void *data)
+static bool cpu_boosting_recv_from_client(int fd, void *data)
{
int client_sock = fd;
}
/* Client asks connect() to the resourced */
-bool cpu_boosting_connect_from_client(int fd, void *data)
+static bool cpu_boosting_connect_from_client(int fd, void *data)
{
int ret;
int master_sock = fd;
- socklen_t len;
- struct sockaddr_un cli = { 0 };
if (master_sock <= 0) {
_E("[CPU-BOOSTING] master socket should be larger than 0");
goto remove_handler;
}
- int new_sock = accept(master_sock, (struct sockaddr *)&cli, &len);
+ int new_sock = accept(master_sock, NULL, NULL);
if (new_sock < 0) {
- _E("[CPU-BOOSTING] Failed to allocate a new socket for the client");
+ _E("[CPU-BOOSTING] Failed to allocate a new socket for the client (%s)", strerror(errno));
goto continue_handler;
}
return RESOURCED_ERROR_NONE;
}
+static int cpu_boosting_thread_activate(void)
+{
+ int ret;
+
+ if (CPU_BOOSTING_WORKER_IS_ACTIVE)
+ return RESOURCED_ERROR_NONE;
+
+ worker.queue = g_async_queue_new_full(cpu_boosting_input_destroy);
+ if (!worker.queue) {
+ _E("[CPU-BOOSTING] Failed to create request queue");
+ return RESOURCED_ERROR_FAIL;
+ }
+
+ /* g_hash_table is not thread safe, so use a lock between threads */
+ if (pthread_mutex_init(&mutex, NULL) != 0) {
+ _E("[CPU-BOOSTING] Failed to initialize mutex");
+ g_async_queue_unref(worker.queue);
+ return RESOURCED_ERROR_FAIL;
+ }
+
+ ret = pthread_create(&worker.thread, NULL,
+ cpu_boosting_func, NULL);
+ if (ret == 0) {
+ pthread_detach(worker.thread);
+ ret = RESOURCED_ERROR_NONE;
+ }
+ else {
+ _E("[CPU-BOOSTING] Failed to create cpu boosting thread");
+ g_async_queue_unref(worker.queue);
+ pthread_mutex_destroy(&mutex);
+ ret = RESOURCED_ERROR_FAIL;
+ }
+
+ return ret;
+}
+
+/* Called by resourced main thread */
+static void cpu_boosting_thread_deactivate(void)
+{
+ if (!CPU_BOOSTING_WORKER_IS_ACTIVE)
+ return;
+
+ CPU_BOOSTING_WORKER_DEACTIVATE;
+ cpu_boosting_drain_queue();
+ g_async_queue_unref(worker.queue);
+ pthread_mutex_destroy(&mutex);
+}
+
/* Called by resourced main thread */
static int cpu_boosting_init(void *data)
{
+ int ret;
+
load_cpu_boosting_configs();
- cpu_boosting_thread_activate();
- tid_table = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, NULL);
+ ret = cpu_boosting_thread_activate();
+ if (ret != RESOURCED_ERROR_NONE)
+ return ret;
+
+ tid_table = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, free);
g_assert(tid_table);
+
/* For the socket-based client */
if (cpu_boosting_init_server() < 0)
_E("[CPU-BOOSTING] Failed to initialize server environment");
/* For the conf-based client */
register_notifier(RESOURCED_NOTIFIER_BOOSTING_RESOURCE, cpu_boosting_enqueue_by_conf);
+
return RESOURCED_ERROR_NONE;
}
static int cpu_boosting_finalize(void *data)
{
cpu_boosting_thread_deactivate();
+ g_hash_table_destroy(tid_table);
unregister_notifier(RESOURCED_NOTIFIER_BOOSTING_RESOURCE, cpu_boosting_enqueue_by_conf);
return RESOURCED_ERROR_NONE;