Workloads


TSLoad supports statically-defined userspace dynamic tracing (USDT) using etrace subsystem.
Build with --enable-usdt (Linux + SystemTap or Solaris + DTrace) or --enable-etw
(Event Tracing for Windows).

Windows:

Linux:

        root@centos# stap -e '
            probe process("../lib/libtsload.so").provider("tsload__workload").mark("request__start") {
                println(user_string(@cast($arg1, "workload_t")->wl_name));
            } '                 -c 'tsexperiment -e ./var/tsload/sample run'

Solaris:

        root@sol11# dtrace -n '
            request-start {
                this->wl_name = (char*) copyin(arg0, 64);
                trace(stringof(this->wl_name));
            }'                     -c 'tsexperiment -e ./var/tsload/sample run'

Constants

RQF_FINISHED, RQF_ONTIME, RQF_STARTED, RQF_SUCCESS


Request flags.
sibling of TSRequestFlag

#define RQF_STARTED 0x0001
#define RQF_SUCCESS 0x0002
#define RQF_ONTIME  0x0004
#define RQF_FINISHED    0x0008

Functions

wl_notify

public


Notify server of workload configuring progress.

done is presented in percent. If status is WLS_FAIL - it would be set to -1,
if status is WLS_SUCCESS or WLS_FINISHED - it would be set to 100

ARGUMENTS

LIBEXPORT void wl_notify(workload_t* wl, wl_status_t status, long progress, char* format, ...)

wl_destroy

public


wl_destroy - destroy workload

LIBEXPORT void wl_destroy(workload_t* wl)

wl_search

public

LIBEXPORT workload_t* wl_search(const char* name)

wl_unconfig, wl_config

public

LIBEXPORT void wl_config(workload_t* wl)
LIBEXPORT void wl_unconfig(workload_t* wl)

wl_provide_step


Provide number of requests for current step

ARGUMENTS

RETURN VALUES
0 if steps are saved, -1 if incorrect step provided or wl_requests is full

int wl_provide_step(workload_t* wl, long step_id, unsigned num_rqs, list_head_t* trace_rqs)

wl_advance_step


Proceed to next step, and return number of requests in it

ARGUMENTS

RETURN VALUES
Workload's step or NULL of no steps are on queue

workload_step_t* wl_advance_step(workload_t* wl)

wl_create_request


Create request structure, append it to requests queue, initialize
For chained workloads inherits parent step and request id

ARGUMENTS

request_t* wl_create_request(workload_t* wl, request_t* parent)

wl_clone_request


Clone request - used by benchmark threadpool dispatcher

request_t* wl_clone_request(request_t* origin)

wl_create_request_trace


Create trace-based requests

request_t* wl_create_request_trace(workload_t* wl, int rq_id, long step, int user_id, int thread_id,ts_time_t sched_time, void* rq_params)

wl_run_request


Run request for execution

void wl_run_request(request_t* rq)

wl_init, wl_fini

public

LIBEXPORT int wl_init(void)
LIBEXPORT void wl_fini(void)

wl_rele, wl_hold


Workload reference tracker. It may be held by
- Creator
- Threadpool it attached to
- Request belongs to it

Last owner released reference frees workload,
but not until creator does that.

void wl_hold(workload_t* wl)
void wl_rele(workload_t* wl)

wl_finish


Finish workload - notify that it was finished

void wl_finish(workload_t* wl)

tsobj_workload_proc, tsobj_request_format_all

public

LIBEXPORT tsobj_node_t* tsobj_request_format_all(list_head_t* rq_list)
workload_t* tsobj_workload_proc(const char* wl_name, const char* wl_type, const char* tp_name, ts_time_t deadline,tsobj_node_t* wl_chain_params, tsobj_node_t* rqsched_params, tsobj_node_t* wl_params)

wl_create


wl_create - create new workload: allocate memory and initialize fields

RETURN VALUES
NULL if malloc had failed or new workload object

workload_t* wl_create(const char* name, wl_type_t* wlt, thread_pool_t* tp) 

wl_destroy_impl


wl_destroy_nodetach - workload destructor

void wl_destroy_impl(workload_t* wl) 

wl_chain_back


Chain workload to backwards of request chain

ARGUMENTS

void wl_chain_back(workload_t* parent, workload_t* wl) 

wl_request_destroy


Destroy request memory

void wl_request_destroy(request_t* rq) 

Types

typedef struct request


Request descriptor

MEMBERS

typedef struct request {
    long rq_step;
    int rq_id;
    int rq_user_id;

    int rq_thread_id;

    ts_time_t rq_sched_time;
    ts_time_t rq_start_time;
    ts_time_t rq_end_time;

    int rq_flags;

    int rq_queue_len;

    struct workload* rq_workload;

    void* rq_params;

    list_node_t rq_node;        /* Next request in chain */
    list_node_t rq_w_node;
    list_node_t rq_wl_node;
    struct request* rq_chain_next;    /* Next request in workload chain */
} request_t;

typedef struct workload_step

typedef struct workload_step {
    struct workload* wls_workload;
    unsigned wls_rq_count;
    list_head_t wls_trace_rqs;
} workload_step_t;

wl_status_t


Workload state

Sibling to TSWorkloadStatusCode

typedef enum {
    WLS_NEW = 0,
    WLS_CHAINED = 1,
    WLS_CONFIGURING = 2,
    WLS_CFG_FAIL = 3,
    WLS_CONFIGURED = 4,
    WLS_STARTED = 5,
    WLS_RUNNING    = 6,
    WLS_FINISHED = 7,
    WLS_DESTROYED = 8
} wl_status_t;

typedef struct workload


Workload primary structure

Workload FSM

wl_create()  -> NEW / CHAINED
                     |
cfg_thread()    --> CONFIGURING
                    /                    /                     /                 CONFIGURED CFG_FAIL
                |        |
              STARTED    |
                |        |
              RUNNING-----+
                |         |
             FINISHED     |
                |         |
             DESTROYED <--+

MEMBERS

typedef struct workload {
    AUTOSTRING char* wl_name;

    wl_type_t*         wl_type;

    thread_pool_t*     wl_tp;
    void*             wl_params;
    void*             wl_private;

    thread_t         wl_cfg_thread;

    thread_mutex_t     wl_status_mutex;
    wl_status_t      wl_status;
    unsigned long     wl_status_flags;

    atomic_t         wl_ref_count;

    int                 wl_current_rq;
    thread_mutex_t     wl_rq_mutex;
    list_head_t         wl_requests;

    ts_time_t         wl_start_time;
    ts_time_t         wl_notify_time;
    ts_time_t         wl_start_clock;
    ts_time_t         wl_time;

    /* Requests queue */
    thread_mutex_t     wl_step_mutex;
    long             wl_current_step;
    long             wl_last_step;
    workload_step_t  wl_step_queue[WLSTEPQSIZE];
    /* End of requests queue*/

    ts_time_t         wl_deadline;

    struct workload* wl_chain_next;
    randgen_t*         wl_chain_rg;
    double             wl_chain_probability;

    struct rqsched_class* wl_rqsched_class;
    struct rqsched* wl_rqsched_private;

    struct workload* wl_hm_next;        /**< next in workload hashmap*/

    list_node_t         wl_tp_node;        /**< thread pool wl list*/

    list_head_t         wl_wlpgen_head;    /**< per-request params*/
} workload_t;

wl_notify_msg_t

typedef struct {
    AUTOSTRING char* wl_name;
    wl_status_t status;
    long progress;

    AUTOSTRING char* msg;
} wl_notify_msg_t;