mirror of
https://github.com/schoebel/mars
synced 2025-01-03 12:52:15 +00:00
fix disconnect of bricks, better copy statistics, various improvements
This commit is contained in:
parent
c5a9ad16ff
commit
4525d28aed
26
brick.c
26
brick.c
@ -789,16 +789,30 @@ int set_recursive_button(struct generic_brick *orig_brick, brick_switch_t mode,
|
|||||||
BRICK_DBG("--> switch '%s' stack = %d\n", SAFE_STR(brick->brick_name), stack);
|
BRICK_DBG("--> switch '%s' stack = %d\n", SAFE_STR(brick->brick_name), stack);
|
||||||
set_button_wait(brick, val, force, timeout);
|
set_button_wait(brick, val, force, timeout);
|
||||||
if (val ? !brick->power.led_on : !brick->power.led_off) {
|
if (val ? !brick->power.led_on : !brick->power.led_off) {
|
||||||
BRICK_DBG("switching to %d: brick '%s' not ready (%s)\n", val, SAFE_STR(brick->brick_name), SAFE_STR(orig_brick->brick_name));
|
BRICK_ERR("switching '%s' to %d: brick not ready (%s)\n", SAFE_STR(brick->brick_name), val, SAFE_STR(orig_brick->brick_name));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (force && !val && (mode == BR_FREE_ONE || mode == BR_FREE_ALL) && brick->free) {
|
if (force && !val && (mode == BR_FREE_ONE || mode == BR_FREE_ALL)) {
|
||||||
|
int i;
|
||||||
BRICK_DBG("---> freeing '%s'\n", SAFE_STR(brick->brick_name));
|
BRICK_DBG("---> freeing '%s'\n", SAFE_STR(brick->brick_name));
|
||||||
status = brick->free(brick);
|
for (i = 0; i < brick->type->max_inputs; i++) {
|
||||||
if (status < 0) {
|
struct generic_input *input = brick->inputs[i];
|
||||||
BRICK_DBG("freeing failed, status = %d\n", status);
|
BRICK_DBG("---> i = %d\n", i);
|
||||||
goto done;
|
if (!input)
|
||||||
|
continue;
|
||||||
|
status = generic_disconnect(input);
|
||||||
|
if (status < 0) {
|
||||||
|
BRICK_ERR("disconnect %d failed, status = %d\n", i, status);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (brick->free) {
|
||||||
|
status = brick->free(brick);
|
||||||
|
if (status < 0) {
|
||||||
|
BRICK_ERR("freeing failed, status = %d\n", status);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
mars.h
4
mars.h
@ -266,8 +266,8 @@ extern const struct meta mars_timespec_meta[];
|
|||||||
#include "sy_old/strategy.h"
|
#include "sy_old/strategy.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void mars_power_led_on(struct generic_brick *brick, bool val);
|
extern void mars_power_led_on(struct mars_brick *brick, bool val);
|
||||||
extern void mars_power_led_off(struct generic_brick *brick, bool val);
|
extern void mars_power_led_off(struct mars_brick *brick, bool val);
|
||||||
/* this should disappear!
|
/* this should disappear!
|
||||||
*/
|
*/
|
||||||
extern void (*_mars_trigger)(void);
|
extern void (*_mars_trigger)(void);
|
||||||
|
@ -313,7 +313,7 @@ int receiver_thread(void *data)
|
|||||||
status = mars_recv_cb(output->socket, mref);
|
status = mars_recv_cb(output->socket, mref);
|
||||||
MARS_IO("new status = %d, pos = %lld len = %d rw = %d\n", status, mref->ref_pos, mref->ref_len, mref->ref_rw);
|
MARS_IO("new status = %d, pos = %lld len = %d rw = %d\n", status, mref->ref_pos, mref->ref_len, mref->ref_rw);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
MARS_ERR("interrupted data transfer during callback, status = %d\n", status);
|
MARS_WRN("interrupted data transfer during callback, status = %d\n", status);
|
||||||
traced_lock(&output->hash_lock[hash_index], flags);
|
traced_lock(&output->hash_lock[hash_index], flags);
|
||||||
list_add_tail(&mref_a->hash_head, &output->hash_table[hash_index]);
|
list_add_tail(&mref_a->hash_head, &output->hash_table[hash_index]);
|
||||||
traced_unlock(&output->hash_lock[hash_index], flags);
|
traced_unlock(&output->hash_lock[hash_index], flags);
|
||||||
@ -325,7 +325,6 @@ int receiver_thread(void *data)
|
|||||||
traced_unlock(&output->lock, flags);
|
traced_unlock(&output->lock, flags);
|
||||||
|
|
||||||
atomic_dec(&output->fly_count);
|
atomic_dec(&output->fly_count);
|
||||||
|
|
||||||
SIMPLE_CALLBACK(mref, 0);
|
SIMPLE_CALLBACK(mref, 0);
|
||||||
client_ref_put(output, mref);
|
client_ref_put(output, mref);
|
||||||
break;
|
break;
|
||||||
@ -333,7 +332,7 @@ int receiver_thread(void *data)
|
|||||||
case CMD_GETINFO:
|
case CMD_GETINFO:
|
||||||
status = mars_recv_struct(output->socket, &output->info, mars_info_meta);
|
status = mars_recv_struct(output->socket, &output->info, mars_info_meta);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
MARS_ERR("got bad info from remote side, status = %d\n", status);
|
MARS_WRN("got bad info from remote side, status = %d\n", status);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
output->got_info = true;
|
output->got_info = true;
|
||||||
@ -488,6 +487,28 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////// informational / statistics ///////////////
|
||||||
|
|
||||||
|
static
|
||||||
|
char *client_statistics(struct client_brick *brick, int verbose)
|
||||||
|
{
|
||||||
|
struct client_output *output = brick->outputs[0];
|
||||||
|
char *res = brick_string_alloc(0);
|
||||||
|
if (!res)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
snprintf(res, 512, "socket = %p fly_count = %d\n",
|
||||||
|
output->socket,
|
||||||
|
atomic_read(&output->fly_count));
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void client_reset_statistics(struct client_brick *brick)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
//////////////// object / aspect constructors / destructors ///////////////
|
//////////////// object / aspect constructors / destructors ///////////////
|
||||||
|
|
||||||
static int client_mref_aspect_init_fn(struct generic_aspect *_ini)
|
static int client_mref_aspect_init_fn(struct generic_aspect *_ini)
|
||||||
@ -546,6 +567,8 @@ static int client_output_destruct(struct client_output *output)
|
|||||||
|
|
||||||
static struct client_brick_ops client_brick_ops = {
|
static struct client_brick_ops client_brick_ops = {
|
||||||
.brick_switch = client_switch,
|
.brick_switch = client_switch,
|
||||||
|
.brick_statistics = client_statistics,
|
||||||
|
.reset_statistics = client_reset_statistics,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct client_output_ops client_output_ops = {
|
static struct client_output_ops client_output_ops = {
|
||||||
|
@ -130,14 +130,14 @@ void copy_endio(struct generic_callback *cb)
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
if (unlikely(cb->cb_error < 0)) {
|
if (unlikely(cb->cb_error < 0)) {
|
||||||
MARS_ERR("IO error %d on index %d, old state = %d\n", cb->cb_error, index, st->state);
|
MARS_DBG("IO error %d on index %d, old state = %d\n", cb->cb_error, index, st->state);
|
||||||
error = cb->cb_error;
|
error = cb->cb_error;
|
||||||
} else if (likely(!st->error)) {
|
} else if (likely(!st->error)) {
|
||||||
st->table[queue] = mref;
|
st->table[queue] = mref;
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (unlikely(error)) {
|
if (unlikely(error < 0)) {
|
||||||
st->error = error;
|
st->error = error;
|
||||||
_clash(brick);
|
_clash(brick);
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,7 @@ EXPORT_SYMBOL_GPL(mars_log_trace);
|
|||||||
|
|
||||||
// power led handling
|
// power led handling
|
||||||
|
|
||||||
void mars_power_led_on(struct generic_brick *brick, bool val)
|
void mars_power_led_on(struct mars_brick *brick, bool val)
|
||||||
{
|
{
|
||||||
bool oldval = brick->power.led_on;
|
bool oldval = brick->power.led_on;
|
||||||
if (val != oldval) {
|
if (val != oldval) {
|
||||||
@ -207,7 +207,7 @@ void mars_power_led_on(struct generic_brick *brick, bool val)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mars_power_led_on);
|
EXPORT_SYMBOL_GPL(mars_power_led_on);
|
||||||
|
|
||||||
void mars_power_led_off(struct generic_brick *brick, bool val)
|
void mars_power_led_off(struct mars_brick *brick, bool val)
|
||||||
{
|
{
|
||||||
bool oldval = brick->power.led_off;
|
bool oldval = brick->power.led_off;
|
||||||
if (val != oldval) {
|
if (val != oldval) {
|
||||||
|
@ -3186,11 +3186,12 @@ static int light_thread(void *data)
|
|||||||
MARS_DBG("worker status = %d\n", status);
|
MARS_DBG("worker status = %d\n", status);
|
||||||
|
|
||||||
if (!_global.global_power.button) {
|
if (!_global.global_power.button) {
|
||||||
status = mars_kill_brick_when_possible(&_global, &_global.brick_anchor, false, (void*)©_brick_type);
|
status = mars_kill_brick_when_possible(&_global, &_global.brick_anchor, false, (void*)©_brick_type, false);
|
||||||
|
MARS_DBG("kill copy bricks (when possible) = %d\n", status);
|
||||||
}
|
}
|
||||||
status = mars_kill_brick_when_possible(&_global, &_global.brick_anchor, false, (void*)&client_brick_type);
|
status = mars_kill_brick_when_possible(&_global, &_global.brick_anchor, false, (void*)&client_brick_type, false);
|
||||||
MARS_DBG("kill client bricks (when possible) = %d\n", status);
|
MARS_DBG("kill client bricks (when possible) = %d\n", status);
|
||||||
status = mars_kill_brick_when_possible(&_global, &_global.brick_anchor, false, (void*)&aio_brick_type);
|
status = mars_kill_brick_when_possible(&_global, &_global.brick_anchor, false, (void*)&aio_brick_type, false);
|
||||||
MARS_DBG("kill aio bricks (when possible) = %d\n", status);
|
MARS_DBG("kill aio bricks (when possible) = %d\n", status);
|
||||||
|
|
||||||
_show_status_all(&_global);
|
_show_status_all(&_global);
|
||||||
|
@ -75,7 +75,7 @@ extern struct mars_brick *mars_make_brick(struct mars_global *global, struct mar
|
|||||||
extern int mars_free_brick(struct mars_brick *brick);
|
extern int mars_free_brick(struct mars_brick *brick);
|
||||||
extern int mars_kill_brick(struct mars_brick *brick);
|
extern int mars_kill_brick(struct mars_brick *brick);
|
||||||
extern int mars_kill_brick_all(struct mars_global *global, struct list_head *anchor, bool use_dent_link);
|
extern int mars_kill_brick_all(struct mars_global *global, struct list_head *anchor, bool use_dent_link);
|
||||||
extern int mars_kill_brick_when_possible(struct mars_global *global, struct list_head *anchor, bool use_dent_link, const struct mars_brick_type *type);
|
extern int mars_kill_brick_when_possible(struct mars_global *global, struct list_head *anchor, bool use_dent_link, const struct mars_brick_type *type, bool only_off);
|
||||||
|
|
||||||
// mid-level brick instantiation (identity is based on path strings)
|
// mid-level brick instantiation (identity is based on path strings)
|
||||||
|
|
||||||
|
@ -954,7 +954,7 @@ int mars_kill_brick(struct mars_brick *brick)
|
|||||||
CHECK_PTR(brick, done);
|
CHECK_PTR(brick, done);
|
||||||
global = brick->global;
|
global = brick->global;
|
||||||
|
|
||||||
MARS_DBG("===> killing brick path = '%s' name = '%s'\n", SAFE_STR(brick->brick_path), SAFE_STR(brick->brick_name));
|
MARS_DBG("===> killing brick %s path = '%s' name = '%s'\n", SAFE_STR(brick->type->type_name), SAFE_STR(brick->brick_path), SAFE_STR(brick->brick_name));
|
||||||
|
|
||||||
if (global) {
|
if (global) {
|
||||||
down_write(&global->brick_mutex);
|
down_write(&global->brick_mutex);
|
||||||
@ -1011,7 +1011,7 @@ int mars_kill_brick_all(struct mars_global *global, struct list_head *anchor, bo
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mars_kill_brick_all);
|
EXPORT_SYMBOL_GPL(mars_kill_brick_all);
|
||||||
|
|
||||||
int mars_kill_brick_when_possible(struct mars_global *global, struct list_head *anchor, bool use_dent_link, const struct mars_brick_type *type)
|
int mars_kill_brick_when_possible(struct mars_global *global, struct list_head *anchor, bool use_dent_link, const struct mars_brick_type *type, bool only_off)
|
||||||
{
|
{
|
||||||
int return_status = 0;
|
int return_status = 0;
|
||||||
struct list_head *tmp;
|
struct list_head *tmp;
|
||||||
@ -1032,15 +1032,18 @@ int mars_kill_brick_when_possible(struct mars_global *global, struct list_head *
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// only kill unconnected bricks
|
// only kill unconnected bricks
|
||||||
if (brick->outputs[0]->nr_connected > 0) {
|
if (brick->outputs[0] && brick->outputs[0]->nr_connected > 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#if 1
|
if (only_off) {
|
||||||
|
MARS_DBG("POWER OFF '%s'\n", brick->brick_name);
|
||||||
|
status = mars_power_button(brick, false, false);
|
||||||
|
goto success;
|
||||||
|
}
|
||||||
/* optimization:
|
/* optimization:
|
||||||
* only kill bricks which have not been touched during the current mars_dent_work() round.
|
* only kill bricks which have not been touched during the current mars_dent_work() round.
|
||||||
* disable this for stress-testing the allocation/deallocation logic.
|
* disable this for stress-testing the allocation/deallocation logic.
|
||||||
*/
|
*/
|
||||||
#endif
|
|
||||||
if (global && global->global_version == brick->brick_version) {
|
if (global && global->global_version == brick->brick_version) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1048,10 +1051,12 @@ int mars_kill_brick_when_possible(struct mars_global *global, struct list_head *
|
|||||||
if (global) {
|
if (global) {
|
||||||
up_write(&global->brick_mutex);
|
up_write(&global->brick_mutex);
|
||||||
}
|
}
|
||||||
|
MARS_DBG("KILLING '%s'\n", brick->brick_name);
|
||||||
status = mars_kill_brick(brick);
|
status = mars_kill_brick(brick);
|
||||||
if (global) {
|
if (global) {
|
||||||
down_write(&global->brick_mutex);
|
down_write(&global->brick_mutex);
|
||||||
}
|
}
|
||||||
|
success:
|
||||||
if (status >= 0) {
|
if (status >= 0) {
|
||||||
return_status++;
|
return_status++;
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user