X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=libust%2Flttng-ust-abi.c;h=6d17c2005dd2999a02ab20f382b0dd525761ef31;hb=4318ae1be57eb7983ab4857a7a8eeb4a030a8216;hp=5f4ba8916da496c0f0b0f5867a996e13fa9b39e1;hpb=46050b1a32de8dd0a7b65347af630c4a77f433a1;p=lttng-ust.git diff --git a/libust/lttng-ust-abi.c b/libust/lttng-ust-abi.c index 5f4ba891..6d17c200 100644 --- a/libust/lttng-ust-abi.c +++ b/libust/lttng-ust-abi.c @@ -24,12 +24,12 @@ * Dual LGPL v2.1/GPL v2 license. */ -#include +#include #include #include -#include -#include -#include "ust/core.h" +#include +#include +#include "lttng/core.h" #include "ltt-tracer.h" /* @@ -37,31 +37,31 @@ * by the caller. */ -struct obj { +struct lttng_ust_obj { union { struct { void *private_data; - const struct objd_ops *ops; + const struct lttng_ust_objd_ops *ops; int f_count; } s; int freelist_next; /* offset freelist. end is -1. */ } u; }; -struct objd_table { - struct obj *array; +struct lttng_ust_objd_table { + struct lttng_ust_obj *array; unsigned int len, allocated_len; int freelist_head; /* offset freelist head. end is -1 */ }; -static struct objd_table objd_table = { +static struct lttng_ust_objd_table objd_table = { .freelist_head = -1, }; static -int objd_alloc(void *private_data, const struct objd_ops *ops) +int objd_alloc(void *private_data, const struct lttng_ust_objd_ops *ops) { - struct obj *obj; + struct lttng_ust_obj *obj; if (objd_table.freelist_head != -1) { obj = &objd_table.array[objd_table.freelist_head]; @@ -71,7 +71,7 @@ int objd_alloc(void *private_data, const struct objd_ops *ops) if (objd_table.len >= objd_table.allocated_len) { unsigned int new_allocated_len, old_allocated_len; - struct obj *new_table, *old_table; + struct lttng_ust_obj *new_table, *old_table; old_allocated_len = objd_table.allocated_len; old_table = objd_table.array; @@ -79,11 +79,11 @@ int objd_alloc(void *private_data, const struct objd_ops *ops) new_allocated_len = 1; else new_allocated_len = old_allocated_len << 1; - new_table = zmalloc(sizeof(struct obj) * new_allocated_len); + new_table = zmalloc(sizeof(struct lttng_ust_obj) * new_allocated_len); if (!new_table) return -ENOMEM; memcpy(new_table, old_table, - sizeof(struct obj) * old_allocated_len); + sizeof(struct lttng_ust_obj) * old_allocated_len); free(old_table); objd_table.array = new_table; objd_table.allocated_len = new_allocated_len; @@ -99,7 +99,7 @@ end: } static -struct obj *_objd_get(int id) +struct lttng_ust_obj *_objd_get(int id) { if (id >= objd_table.len) return NULL; @@ -111,7 +111,7 @@ struct obj *_objd_get(int id) static void *objd_private(int id) { - struct obj *obj = _objd_get(id); + struct lttng_ust_obj *obj = _objd_get(id); assert(obj); return obj->u.s.private_data; } @@ -119,14 +119,14 @@ void *objd_private(int id) static void objd_set_private(int id, void *private_data) { - struct obj *obj = _objd_get(id); + struct lttng_ust_obj *obj = _objd_get(id); assert(obj); obj->u.s.private_data = private_data; } -const struct objd_ops *objd_ops(int id) +const struct lttng_ust_objd_ops *objd_ops(int id) { - struct obj *obj = _objd_get(id); + struct lttng_ust_obj *obj = _objd_get(id); if (!obj) return NULL; @@ -136,7 +136,7 @@ const struct objd_ops *objd_ops(int id) static void objd_free(int id) { - struct obj *obj = _objd_get(id); + struct lttng_ust_obj *obj = _objd_get(id); assert(obj); obj->u.freelist_next = objd_table.freelist_head; @@ -148,13 +148,13 @@ void objd_free(int id) static void objd_ref(int id) { - struct obj *obj = _objd_get(id); + struct lttng_ust_obj *obj = _objd_get(id); obj->u.s.f_count++; } -int objd_unref(int id) +int lttng_ust_objd_unref(int id) { - struct obj *obj = _objd_get(id); + struct lttng_ust_obj *obj = _objd_get(id); if (!obj) return -EINVAL; @@ -163,7 +163,7 @@ int objd_unref(int id) return -EINVAL; } if ((--obj->u.s.f_count) == 1) { - const struct objd_ops *ops = objd_ops(id); + const struct lttng_ust_objd_ops *ops = objd_ops(id); if (ops->release) ops->release(id); @@ -177,17 +177,13 @@ void objd_table_destroy(void) { int i; - for (i = 0; i < objd_table.allocated_len; i++) { - struct obj *obj = _objd_get(i); - const struct objd_ops *ops; - - if (!obj) - continue; - ops = obj->u.s.ops; - if (ops->release) - ops->release(i); - } + for (i = 0; i < objd_table.allocated_len; i++) + (void) lttng_ust_objd_unref(i); free(objd_table.array); + objd_table.array = NULL; + objd_table.len = 0; + objd_table.allocated_len = 0; + objd_table.freelist_head = -1; } /* @@ -195,11 +191,12 @@ void objd_table_destroy(void) * We send commands over a socket. */ -static const struct objd_ops lttng_ops; -static const struct objd_ops lttng_session_ops; -static const struct objd_ops lttng_channel_ops; -static const struct objd_ops lttng_metadata_ops; -static const struct objd_ops lttng_event_ops; +static const struct lttng_ust_objd_ops lttng_ops; +static const struct lttng_ust_objd_ops lttng_session_ops; +static const struct lttng_ust_objd_ops lttng_channel_ops; +static const struct lttng_ust_objd_ops lttng_metadata_ops; +static const struct lttng_ust_objd_ops lttng_event_ops; +static const struct lttng_ust_objd_ops lib_ring_buffer_objd_ops; enum channel_type { PER_CPU_CHANNEL, @@ -211,10 +208,10 @@ int lttng_abi_create_root_handle(void) int root_handle; root_handle = objd_alloc(NULL, <tng_ops); - assert(root_handle == 0); return root_handle; } +static int lttng_abi_create_session(void) { struct ltt_session *session; @@ -275,8 +272,14 @@ long lttng_abi_add_context(int objd, return -EPERM; switch (context_param->ctx) { + case LTTNG_UST_CONTEXT_PTHREAD_ID: + return lttng_add_pthread_id_to_ctx(ctx); case LTTNG_UST_CONTEXT_VTID: - //TODO return lttng_add_vtid_to_ctx(ctx); + return lttng_add_vtid_to_ctx(ctx); + case LTTNG_UST_CONTEXT_VPID: + return lttng_add_vpid_to_ctx(ctx); + case LTTNG_UST_CONTEXT_PROCNAME: + return lttng_add_procname_to_ctx(ctx); default: return -EINVAL; } @@ -321,7 +324,7 @@ long lttng_cmd(int objd, unsigned int cmd, unsigned long arg) } } -static const struct objd_ops lttng_ops = { +static const struct lttng_ust_objd_ops lttng_ops = { .cmd = lttng_cmd, }; @@ -362,7 +365,7 @@ int lttng_abi_create_channel(int session_objd, enum channel_type channel_type) { struct ltt_session *session = objd_private(session_objd); - const struct objd_ops *ops; + const struct lttng_ust_objd_ops *ops; const char *transport_name; struct ltt_channel *chan; int chan_objd; @@ -402,7 +405,10 @@ int lttng_abi_create_channel(int session_objd, chan_param->subbuf_size, chan_param->num_subbuf, chan_param->switch_timer_interval, - chan_param->read_timer_interval); + chan_param->read_timer_interval, + &chan_param->shm_fd, + &chan_param->wait_fd, + &chan_param->memory_map_size); if (!chan) { ret = -EINVAL; goto chan_error; @@ -423,7 +429,7 @@ chan_error: { int err; - err = objd_unref(chan_objd); + err = lttng_ust_objd_unref(chan_objd); assert(!err); } objd_error: @@ -495,40 +501,51 @@ int lttng_release_session(int objd) } } -static const struct objd_ops lttng_session_ops = { +static const struct lttng_ust_objd_ops lttng_session_ops = { .release = lttng_release_session, .cmd = lttng_session_cmd, }; -#if 0 +struct stream_priv_data { + struct lttng_ust_lib_ring_buffer *buf; + struct ltt_channel *ltt_chan; +}; + static -int lttng_abi_open_stream(int channel_objd) +int lttng_abi_open_stream(int channel_objd, struct lttng_ust_stream *info) { struct ltt_channel *channel = objd_private(channel_objd); - struct lib_ring_buffer *buf; + struct lttng_ust_lib_ring_buffer *buf; + struct stream_priv_data *priv; int stream_objd, ret; - buf = channel->ops->buffer_read_open(channel->chan); + buf = channel->ops->buffer_read_open(channel->chan, channel->handle, + &info->shm_fd, &info->wait_fd, &info->memory_map_size); if (!buf) return -ENOENT; - stream_objd = objd_alloc(buf, &lib_ring_buffer_objd_ops); + priv = zmalloc(sizeof(*priv)); + if (!priv) { + ret = -ENOMEM; + goto alloc_error; + } + priv->buf = buf; + priv->ltt_chan = channel; + stream_objd = objd_alloc(priv, &lib_ring_buffer_objd_ops); if (stream_objd < 0) { ret = stream_objd; goto objd_error; } - /* - * The stream holds a reference to the channel within the generic ring - * buffer library, so no need to hold a refcount on the channel and - * session files here. - */ + /* Hold a reference on the channel object descriptor */ + objd_ref(channel_objd); return stream_objd; objd_error: - channel->ops->buffer_read_close(buf); + free(priv); +alloc_error: + channel->ops->buffer_read_close(buf, channel->handle); return ret; } -#endif //0 static int lttng_abi_create_event(int channel_objd, @@ -562,7 +579,7 @@ event_error: { int err; - err = objd_unref(event_objd); + err = lttng_ust_objd_unref(event_objd); assert(!err); } objd_error: @@ -598,8 +615,13 @@ long lttng_channel_cmd(int objd, unsigned int cmd, unsigned long arg) switch (cmd) { case LTTNG_UST_STREAM: - return -ENOSYS; //TODO - //return lttng_abi_open_stream(objd); + { + struct lttng_ust_stream *stream; + + stream = (struct lttng_ust_stream *) arg; + /* stream used as output */ + return lttng_abi_open_stream(objd, stream); + } case LTTNG_UST_EVENT: return lttng_abi_create_event(objd, (struct lttng_ust_event *) arg); case LTTNG_UST_CONTEXT: @@ -610,6 +632,8 @@ long lttng_channel_cmd(int objd, unsigned int cmd, unsigned long arg) return ltt_channel_enable(channel); case LTTNG_UST_DISABLE: return ltt_channel_disable(channel); + case LTTNG_UST_FLUSH_BUFFER: + return channel->ops->flush_buffer(channel->chan, channel->handle); default: return -EINVAL; } @@ -631,10 +655,19 @@ long lttng_channel_cmd(int objd, unsigned int cmd, unsigned long arg) static long lttng_metadata_cmd(int objd, unsigned int cmd, unsigned long arg) { + struct ltt_channel *channel = objd_private(objd); + switch (cmd) { case LTTNG_UST_STREAM: - return -ENOSYS; //TODO - //return lttng_abi_open_stream(objd); + { + struct lttng_ust_stream *stream; + + stream = (struct lttng_ust_stream *) arg; + /* stream used as output */ + return lttng_abi_open_stream(objd, stream); + } + case LTTNG_UST_FLUSH_BUFFER: + return channel->ops->flush_buffer(channel->chan, channel->handle); default: return -EINVAL; } @@ -676,21 +709,63 @@ int lttng_channel_release(int objd) struct ltt_channel *channel = objd_private(objd); if (channel) - return objd_unref(channel->session->objd); + return lttng_ust_objd_unref(channel->session->objd); return 0; } -static const struct objd_ops lttng_channel_ops = { +static const struct lttng_ust_objd_ops lttng_channel_ops = { .release = lttng_channel_release, //.poll = lttng_channel_poll, .cmd = lttng_channel_cmd, }; -static const struct objd_ops lttng_metadata_ops = { +static const struct lttng_ust_objd_ops lttng_metadata_ops = { .release = lttng_channel_release, .cmd = lttng_metadata_cmd, }; +/** + * lttng_rb_cmd - lttng ring buffer control through object descriptors + * + * @objd: the object descriptor + * @cmd: the command + * @arg: command arg + * + * This object descriptor implements lttng commands: + * (None for now. Access is done directly though shm.) + */ +static +long lttng_rb_cmd(int objd, unsigned int cmd, unsigned long arg) +{ + switch (cmd) { + default: + return -EINVAL; + } +} + +static +int lttng_rb_release(int objd) +{ + struct stream_priv_data *priv = objd_private(objd); + struct lttng_ust_lib_ring_buffer *buf; + struct ltt_channel *channel; + + if (priv) { + buf = priv->buf; + channel = priv->ltt_chan; + free(priv); + channel->ops->buffer_read_close(buf, channel->handle); + + return lttng_ust_objd_unref(channel->objd); + } + return 0; +} + +static const struct lttng_ust_objd_ops lib_ring_buffer_objd_ops = { + .release = lttng_rb_release, + .cmd = lttng_rb_cmd, +}; + /** * lttng_event_cmd - lttng control through object descriptors * @@ -731,12 +806,12 @@ int lttng_event_release(int objd) struct ltt_event *event = objd_private(objd); if (event) - return objd_unref(event->chan->objd); + return lttng_ust_objd_unref(event->chan->objd); return 0; } /* TODO: filter control ioctl */ -static const struct objd_ops lttng_event_ops = { +static const struct lttng_ust_objd_ops lttng_event_ops = { .release = lttng_event_release, .cmd = lttng_event_cmd, };