mirror of
https://github.com/schoebel/mars
synced 2024-12-26 08:32:24 +00:00
import mars-23.tgz
This commit is contained in:
parent
2241b44dd9
commit
c06d7d0c4c
27
brick.c
27
brick.c
@ -119,7 +119,7 @@ int generic_brick_init_full(
|
|||||||
data += sizeof(void*) * brick_type->max_outputs;
|
data += sizeof(void*) * brick_type->max_outputs;
|
||||||
size -= sizeof(void*) * brick_type->max_outputs;
|
size -= sizeof(void*) * brick_type->max_outputs;
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
return -1;
|
return -ENOMEM;
|
||||||
for (i = 0; i < brick_type->max_outputs; i++) {
|
for (i = 0; i < brick_type->max_outputs; i++) {
|
||||||
struct generic_output *output = data;
|
struct generic_output *output = data;
|
||||||
const struct generic_output_type *type = *output_types++;
|
const struct generic_output_type *type = *output_types++;
|
||||||
@ -335,12 +335,25 @@ EXPORT_SYMBOL_GPL(generic_add_aspect);
|
|||||||
|
|
||||||
int default_init_object_layout(struct generic_output *output, struct generic_object_layout *object_layout, int aspect_max, const struct generic_object_type *object_type)
|
int default_init_object_layout(struct generic_output *output, struct generic_object_layout *object_layout, int aspect_max, const struct generic_object_type *object_type)
|
||||||
{
|
{
|
||||||
|
// TODO: make locking granularity finer (if it were worth).
|
||||||
|
static DEFINE_SPINLOCK(global_lock);
|
||||||
void *data;
|
void *data;
|
||||||
int status;
|
int status= -ENOMEM;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
data = kzalloc(aspect_max * sizeof(void*), GFP_MARS);
|
data = kzalloc(aspect_max * sizeof(void*), GFP_MARS);
|
||||||
if (!data)
|
if (unlikely(!data))
|
||||||
return -ENOMEM;
|
goto done;
|
||||||
|
|
||||||
|
traced_lock(&global_lock, flags);
|
||||||
|
|
||||||
|
if (unlikely(object_layout->object_type)) {
|
||||||
|
traced_unlock(&global_lock, flags);
|
||||||
|
BRICK_INF("lost the race on object_layout %p (no harm)\n", object_layout);
|
||||||
|
status = 0;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
object_layout->aspect_layouts = data;
|
object_layout->aspect_layouts = data;
|
||||||
object_layout->object_type = object_type;
|
object_layout->object_type = object_type;
|
||||||
object_layout->aspect_count = 0;
|
object_layout->aspect_count = 0;
|
||||||
@ -348,12 +361,16 @@ int default_init_object_layout(struct generic_output *output, struct generic_obj
|
|||||||
object_layout->object_size = object_type->default_size;
|
object_layout->object_size = object_type->default_size;
|
||||||
|
|
||||||
status = output->ops->make_object_layout(output, object_layout);
|
status = output->ops->make_object_layout(output, object_layout);
|
||||||
|
|
||||||
|
traced_unlock(&global_lock, flags);
|
||||||
|
|
||||||
if (unlikely(status < 0)) {
|
if (unlikely(status < 0)) {
|
||||||
|
object_layout->object_type = NULL;
|
||||||
kfree(data);
|
kfree(data);
|
||||||
object_layout->object_type = NULL;
|
|
||||||
BRICK_ERR("emergency, cannot add aspects to object_layout %s!\n", object_type->object_type_name);
|
BRICK_ERR("emergency, cannot add aspects to object_layout %s!\n", object_type->object_type_name);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
BRICK_INF("OK, object_layout %s init succeeded.\n", object_type->object_type_name);
|
BRICK_INF("OK, object_layout %s init succeeded.\n", object_type->object_type_name);
|
||||||
done:
|
done:
|
||||||
return status;
|
return status;
|
||||||
|
2
brick.h
2
brick.h
@ -484,7 +484,7 @@ extern inline struct BRICK##_##PREFIX##_aspect *BRICK##_##PREFIX##_get_aspect(st
|
|||||||
\
|
\
|
||||||
extern inline int BRICK##_##PREFIX##_init_object_layout(struct BRICK##_output *output, struct generic_object_layout *object_layout) \
|
extern inline int BRICK##_##PREFIX##_init_object_layout(struct BRICK##_output *output, struct generic_object_layout *object_layout) \
|
||||||
{ \
|
{ \
|
||||||
return BRICK##_init_object_layout(output, object_layout, 16, &PREFIX##_type); \
|
return BRICK##_init_object_layout(output, object_layout, 32, &PREFIX##_type); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
extern inline struct PREFIX##_object *BRICK##_alloc_##PREFIX(struct BRICK##_output *output, struct generic_object_layout *object_layout) \
|
extern inline struct PREFIX##_object *BRICK##_alloc_##PREFIX(struct BRICK##_output *output, struct generic_object_layout *object_layout) \
|
||||||
|
34
mars_check.c
34
mars_check.c
@ -23,14 +23,27 @@
|
|||||||
static void check_buf_endio(struct mars_buf_object *mbuf)
|
static void check_buf_endio(struct mars_buf_object *mbuf)
|
||||||
{
|
{
|
||||||
struct check_output *output = mbuf->cb_private;
|
struct check_output *output = mbuf->cb_private;
|
||||||
|
struct check_input *input = output->brick->inputs[0];
|
||||||
struct check_mars_buf_aspect *mbuf_a = check_mars_buf_get_aspect(output, mbuf);
|
struct check_mars_buf_aspect *mbuf_a = check_mars_buf_get_aspect(output, mbuf);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (!mbuf_a) {
|
||||||
|
MARS_FAT("cannot get aspect -- hanging up\n");
|
||||||
|
msleep(60000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
traced_lock(&output->lock, flags);
|
traced_lock(&output->lock, flags);
|
||||||
|
|
||||||
|
if (mbuf_a->call_count-- < 0) {
|
||||||
|
mbuf_a->call_count = 0;
|
||||||
|
MARS_ERR("instance %d/%s: too many callbacks on %p\n", output->instance_nr, input->connect->type->type_name, mbuf);
|
||||||
|
}
|
||||||
if (list_empty(&mbuf_a->mbuf_head)) {
|
if (list_empty(&mbuf_a->mbuf_head)) {
|
||||||
MARS_ERR("mbuf callback called twice on %p\n", mbuf);
|
MARS_ERR("instance %d/%s: list entry missing on %p\n", output->instance_nr, input->connect->type->type_name, mbuf);
|
||||||
}
|
}
|
||||||
list_del_init(&mbuf_a->mbuf_head);
|
list_del_init(&mbuf_a->mbuf_head);
|
||||||
|
|
||||||
traced_unlock(&output->lock, flags);
|
traced_unlock(&output->lock, flags);
|
||||||
|
|
||||||
mbuf->cb_private = mbuf_a->old_private;
|
mbuf->cb_private = mbuf_a->old_private;
|
||||||
@ -134,9 +147,21 @@ static void check_buf_io(struct check_output *output, struct mars_buf_object *mb
|
|||||||
struct check_input *input = output->brick->inputs[0];
|
struct check_input *input = output->brick->inputs[0];
|
||||||
struct check_mars_buf_aspect *mbuf_a = check_mars_buf_get_aspect(output, mbuf);
|
struct check_mars_buf_aspect *mbuf_a = check_mars_buf_get_aspect(output, mbuf);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (!mbuf_a) {
|
||||||
|
MARS_FAT("cannot get aspect -- hanging up\n");
|
||||||
|
msleep(60000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
traced_lock(&output->lock, flags);
|
traced_lock(&output->lock, flags);
|
||||||
|
if (mbuf_a->call_count++ > 1) {
|
||||||
|
mbuf_a->call_count = 1;
|
||||||
|
MARS_ERR("instance %d/%s: multiple parallel calls on %p\n", output->instance_nr, input->connect->type->type_name, mbuf);
|
||||||
|
}
|
||||||
if (!list_empty(&mbuf_a->mbuf_head)) {
|
if (!list_empty(&mbuf_a->mbuf_head)) {
|
||||||
MARS_ERR("instance %d: multiple buf_endio() in parallel on %p\n", output->instance_nr, mbuf);
|
list_del(&mbuf_a->mbuf_head);
|
||||||
|
MARS_ERR("instance %d/%s: list head not empty on %p\n", output->instance_nr, input->connect->type->type_name, mbuf);
|
||||||
}
|
}
|
||||||
list_add_tail(&mbuf_a->mbuf_head, &output->mbuf_anchor);
|
list_add_tail(&mbuf_a->mbuf_head, &output->mbuf_anchor);
|
||||||
if (mbuf->cb_buf_endio != check_buf_endio) {
|
if (mbuf->cb_buf_endio != check_buf_endio) {
|
||||||
@ -147,6 +172,7 @@ static void check_buf_io(struct check_output *output, struct mars_buf_object *mb
|
|||||||
}
|
}
|
||||||
mbuf_a->last_jiffies = jiffies;
|
mbuf_a->last_jiffies = jiffies;
|
||||||
traced_unlock(&output->lock, flags);
|
traced_unlock(&output->lock, flags);
|
||||||
|
|
||||||
GENERIC_INPUT_CALL(input, mars_buf_io, mbuf, rw);
|
GENERIC_INPUT_CALL(input, mars_buf_io, mbuf, rw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,6 +182,7 @@ static int check_mars_buf_aspect_init_fn(struct generic_aspect *_ini, void *_ini
|
|||||||
{
|
{
|
||||||
struct check_mars_buf_aspect *ini = (void*)_ini;
|
struct check_mars_buf_aspect *ini = (void*)_ini;
|
||||||
INIT_LIST_HEAD(&ini->mbuf_head);
|
INIT_LIST_HEAD(&ini->mbuf_head);
|
||||||
|
ini->call_count = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,10 +199,11 @@ static int check_output_construct(struct check_output *output)
|
|||||||
{
|
{
|
||||||
static int count = 0;
|
static int count = 0;
|
||||||
struct task_struct *watchdog;
|
struct task_struct *watchdog;
|
||||||
|
|
||||||
spin_lock_init(&output->lock);
|
spin_lock_init(&output->lock);
|
||||||
|
output->instance_nr = ++count;
|
||||||
INIT_LIST_HEAD(&output->mio_anchor);
|
INIT_LIST_HEAD(&output->mio_anchor);
|
||||||
INIT_LIST_HEAD(&output->mbuf_anchor);
|
INIT_LIST_HEAD(&output->mbuf_anchor);
|
||||||
output->instance_nr = ++count;
|
|
||||||
watchdog = kthread_create(check_watchdog, output, "check_watchdog%d", output->instance_nr);
|
watchdog = kthread_create(check_watchdog, output, "check_watchdog%d", output->instance_nr);
|
||||||
if (!IS_ERR(watchdog)) {
|
if (!IS_ERR(watchdog)) {
|
||||||
output->watchdog = watchdog;
|
output->watchdog = watchdog;
|
||||||
|
@ -8,6 +8,7 @@ struct check_mars_buf_aspect {
|
|||||||
void (*old_buf_endio)(struct mars_buf_object *mbuf);
|
void (*old_buf_endio)(struct mars_buf_object *mbuf);
|
||||||
void *old_private;
|
void *old_private;
|
||||||
unsigned long last_jiffies;
|
unsigned long last_jiffies;
|
||||||
|
int call_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct check_brick {
|
struct check_brick {
|
||||||
|
47
mars_test.c
47
mars_test.c
@ -41,16 +41,37 @@ void make_test_instance(void)
|
|||||||
void *brick(const void *_brick_type)
|
void *brick(const void *_brick_type)
|
||||||
{
|
{
|
||||||
const struct generic_brick_type *brick_type = _brick_type;
|
const struct generic_brick_type *brick_type = _brick_type;
|
||||||
void *mem = kzalloc(brick_type->brick_size, GFP_MARS);
|
const struct generic_input_type **input_types;
|
||||||
|
const struct generic_output_type **output_types;
|
||||||
|
void *mem;
|
||||||
|
int size;
|
||||||
|
int i;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
|
size = brick_type->brick_size +
|
||||||
|
(brick_type->max_inputs + brick_type->max_outputs) * sizeof(void*);
|
||||||
|
input_types = brick_type->default_input_types;
|
||||||
|
for (i = 0; i < brick_type->max_inputs; i++) {
|
||||||
|
const struct generic_input_type *type = *input_types++;
|
||||||
|
size += type->input_size;
|
||||||
|
}
|
||||||
|
output_types = brick_type->default_output_types;
|
||||||
|
for (i = 0; i < brick_type->max_outputs; i++) {
|
||||||
|
const struct generic_output_type *type = *output_types++;
|
||||||
|
size += type->output_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
mem = kzalloc(size, GFP_MARS);
|
||||||
if (!mem) {
|
if (!mem) {
|
||||||
MARS_ERR("cannot grab test memory\n");
|
MARS_ERR("cannot grab test memory for %s\n", brick_type->type_name);
|
||||||
|
msleep(60000);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
status = generic_brick_init_full(mem, brick_type->brick_size, brick_type, NULL, NULL, names);
|
status = generic_brick_init_full(mem, size, brick_type, NULL, NULL, names);
|
||||||
MARS_DBG("done (status=%d)\n", status);
|
MARS_DBG("done (status=%d)\n", status);
|
||||||
if (status) {
|
if (status) {
|
||||||
MARS_ERR("cannot init brick device_sio\n");
|
MARS_ERR("cannot init brick %s\n", brick_type->type_name);
|
||||||
|
msleep(60000);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return mem;
|
return mem;
|
||||||
@ -58,8 +79,22 @@ void make_test_instance(void)
|
|||||||
|
|
||||||
void connect(struct generic_input *a, struct generic_output *b)
|
void connect(struct generic_input *a, struct generic_output *b)
|
||||||
{
|
{
|
||||||
int status = generic_connect(a, b);
|
int status;
|
||||||
|
#if 1
|
||||||
|
struct generic_brick *tmp = brick(&check_brick_type);
|
||||||
|
|
||||||
|
status = generic_connect(a, tmp->outputs[0]);
|
||||||
MARS_DBG("connect (status=%d)\n", status);
|
MARS_DBG("connect (status=%d)\n", status);
|
||||||
|
if (status < 0)
|
||||||
|
msleep(60000);
|
||||||
|
|
||||||
|
status = generic_connect(tmp->inputs[0], b);
|
||||||
|
#else
|
||||||
|
status = generic_connect(a, b);
|
||||||
|
#endif
|
||||||
|
MARS_DBG("connect (status=%d)\n", status);
|
||||||
|
if (status < 0)
|
||||||
|
msleep(60000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -121,6 +156,8 @@ void make_test_instance(void)
|
|||||||
(void)test_endio;
|
(void)test_endio;
|
||||||
connect(last, device_brick->outputs[0]);
|
connect(last, device_brick->outputs[0]);
|
||||||
#endif
|
#endif
|
||||||
|
msleep(1000);
|
||||||
|
MARS_INF("------------- DONE --------------\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy_test_instance(void)
|
void destroy_test_instance(void)
|
||||||
|
Loading…
Reference in New Issue
Block a user