Example #1
0
static RwTaskletPluginInstanceHandle *
rwlogd__component__instance_alloc(RwTaskletPluginComponent *self,
					RwTaskletPluginComponentHandle *h_component,
					struct rwtasklet_info_s * rwtasklet_info,
					RwTaskletPlugin_RWExecURL* instance_url)
{
  rwlogd_component_ptr_t component;
  rwlogd_instance_ptr_t instance;
  RwTaskletPluginInstanceHandle *h_instance;
  gpointer handle;

  // Validate input parameters
  component = (rwlogd_component_ptr_t) h_component->priv;
  RW_CF_TYPE_VALIDATE(component, rwlogd_component_ptr_t);

  // Allocate a new rwlogd_instance structure
  instance = RW_CF_TYPE_MALLOC0(sizeof(*instance), rwlogd_instance_ptr_t);
  RW_CF_TYPE_VALIDATE(instance, rwlogd_instance_ptr_t);

  // Save the rwtasklet_info structure
  instance->rwtasklet_info = rwtasklet_info;

  // Allocate a gobject for the handle
  handle = g_object_new(RW_TASKLET_PLUGIN_TYPE_INSTANCE_HANDLE, 0);
  h_instance = RW_TASKLET_PLUGIN_INSTANCE_HANDLE(handle);
  h_instance->priv = (gpointer) instance;

  // Return the handle to the rwtasklet instance
  return h_instance;
}
Example #2
0
rwmsg_toytask_t *
rwmsg_toytask_create(rwmsg_toysched_t *ts)
{
  rwmsg_toysched_t *toysched = ts;
  rwsched_instance_ptr_t instance;
  rwmsg_toytask_t *toytask;
  static int toytask_id;
  
  // Get the rwsched instance from toysched
  instance = toysched->rwsched_instance;
  RW_CF_TYPE_VALIDATE(instance, rwsched_instance_ptr_t);

  // Allocate memory for the new toytask
  toytask = RW_CF_TYPE_MALLOC0(sizeof(*toytask), rwtoytask_tasklet_ptr_t);
  RW_CF_TYPE_VALIDATE(toytask, rwtoytask_tasklet_ptr_t);
  toytask->rwsched_tasklet_info = rwsched_tasklet_new(instance);

  // Save the toysched instance struture within the toytask
  toytask->toysched = ts;

  // Get the next toytask id for this toytask
  toytask_id++;

  // Return the toytask pointer
  return toytask;
}
Example #3
0
rwsched_tasklet_t *
rwsched_tasklet_new(rwsched_instance_t *instance)
{
  rwsched_tasklet_ptr_t sched_tasklet;
  //int i;

  // Validate input paraemters
  RW_CF_TYPE_VALIDATE(instance, rwsched_instance_ptr_t);

  // Allocate memory for the new sched_tasklet sched_tasklet structure and track it
  sched_tasklet = RW_CF_TYPE_MALLOC0(sizeof(*sched_tasklet), rwsched_tasklet_ptr_t);
  RW_CF_TYPE_VALIDATE(sched_tasklet, rwsched_tasklet_ptr_t);

  rwsched_instance_ref(instance);
  sched_tasklet->instance = instance;
  sched_tasklet->rwresource_track_handle = RW_RESOURCE_TRACK_CREATE_CONTEXT("Tasklet Context");

  // Look for an unused entry in tasklet_array (start the indexes at 1 for now)
  int i; for (i = 1 ; i < instance->tasklet_array->len ; i++) {
    if (g_array_index(instance->tasklet_array, rwsched_tasklet_ptr_t, i) == NULL) {
      g_array_index(instance->tasklet_array, rwsched_tasklet_ptr_t, i) = sched_tasklet;
      break;
    }
  }
  if (i >= instance->tasklet_array->len) {
    // Insert a new element at the end of the array
    g_array_append_val(instance->tasklet_array, sched_tasklet);
  }


#ifdef _CF_
  // Allocate an array of cftimer pointers and track it
  rwsched_CFRunLoopTimerRef cftimer = NULL;
  sched_tasklet->cftimer_array = g_array_sized_new(TRUE, TRUE, sizeof(void *), 256);
  g_array_append_val(sched_tasklet->cftimer_array, cftimer);

  // Allocate an array of cfsocket pointers and track it
  rwsched_CFSocketRef cfsocket = NULL;
  sched_tasklet->cfsocket_array = g_array_sized_new(TRUE, TRUE, sizeof(void *), 256);
  g_array_append_val(sched_tasklet->cfsocket_array, cfsocket);

  // Allocate an array of cfsocket pointers and track it
  rwsched_CFRunLoopSourceRef cfsource = NULL;
  sched_tasklet->cfsource_array = g_array_sized_new(TRUE, TRUE, sizeof(void *), 256);
  g_array_append_val(sched_tasklet->cfsource_array, cfsource);

  // Allocate an array of dispatch_what pointers and track it
  rwsched_dispatch_what_ptr_t dispatch_what = NULL;
  sched_tasklet->dispatch_what_array = g_array_sized_new(TRUE, TRUE, sizeof(void *), 256);
  g_array_append_val(sched_tasklet->dispatch_what_array, dispatch_what);
#endif

  rwsched_tasklet_ref(sched_tasklet);
  ck_pr_inc_32(&g_rwsched_tasklet_count);

  // Return the allocated sched_tasklet sched_tasklet structure
  return sched_tasklet;
}
Example #4
0
rwdtsperf_component_ptr_t rwdtsperf_component_init(void)
{
  rwdtsperf_component_ptr_t component;

  // Allocate a new rwdtsperf_component structure
  component = RW_CF_TYPE_MALLOC0(sizeof(*component), rwdtsperf_component_ptr_t);
  RW_CF_TYPE_VALIDATE(component, rwdtsperf_component_ptr_t);

  // Return the allocated component
  return component;
}
Example #5
0
uint64_t
rwmsg_toyRtimer_add(rwmsg_toytask_t *toy, int ms, toytimer_cb_t cb, void *ud)
{
  rwsched_instance_ptr_t instance;
  rwmsg_toytask_t *toytask = toy;
  struct rwmsg_toytimer_s *toytimer;
  //uint64_t nsec;

  // Validate input parameters
  RW_CF_TYPE_VALIDATE(toytask, rwtoytask_tasklet_ptr_t);

  // Get the rwsched instance from the toytask
  instance = toytask->toysched->rwsched_instance;
  RW_CF_TYPE_VALIDATE(instance, rwsched_instance_ptr_t);

  // Allocate a toytimer container type and track it
  toytimer = RW_CF_TYPE_MALLOC0(sizeof(*toytimer), rwmsg_toytimer_ptr_t);
  RW_CF_TYPE_VALIDATE(toytimer, rwmsg_toytimer_ptr_t);
  
  // Create a CF runloop timer
  CFRunLoopTimerContext cf_context = { 0, NULL, NULL, NULL, NULL };
  double timer_interval = ms * .001;
  rwsched_CFRunLoopRef runloop = rwsched_tasklet_CFRunLoopGetCurrent(toytask->rwsched_tasklet_info);
  rwsched_CFRunLoopTimerRef cftimer;

  // Create a CFRunLoopTimer as a runloop source for the toytimer
  cf_context.info = toytimer;
  cftimer = rwsched_tasklet_CFRunLoopTimerCreate(toytask->rwsched_tasklet_info,
					 kCFAllocatorDefault,
					 CFAbsoluteTimeGetCurrent() + timer_interval,
					 timer_interval,
					 0,
					 0,
					 rwmsg_toysched_Rtimer_callback,
					 &cf_context);
  RW_CF_TYPE_VALIDATE(cftimer, rwsched_CFRunLoopTimerRef);
  rwsched_tasklet_CFRunLoopAddTimer(toytask->rwsched_tasklet_info, runloop, cftimer, instance->main_cfrunloop_mode);

  // Fill in the toytimer structure
  toytimer->id = cftimer->index;
  toytimer->cb = cb;
  toytimer->ud = ud;

  // Fill in the toytimer context structure
  toytimer->context.toytask = toy;
  toytimer->context.source.cftimer = cftimer;
  toytimer->context.u.toytimer.toytimer = toytimer;

  // Return the callback id
  return (uint64_t) toytimer->id;
}
Example #6
0
rwdtsperf_instance_ptr_t rwdtsperf_instance_alloc(rwdtsperf_component_ptr_t component,
			                                  struct rwtasklet_info_s * rwtasklet_info,
			                                  RwTaskletPlugin_RWExecURL *instance_url)
{
  rwdtsperf_instance_ptr_t instance;

  // Validate input parameters
  RW_CF_TYPE_VALIDATE(component, rwdtsperf_component_ptr_t);
  RW_ASSERT(instance_url);

  // Allocate a new rwdtsperf_instance structure
  instance = RW_CF_TYPE_MALLOC0(sizeof(*instance), rwdtsperf_instance_ptr_t);
  RW_CF_TYPE_VALIDATE(instance, rwdtsperf_instance_ptr_t);

  // Save the rwtasklet_info structure
  instance->rwtasklet_info = rwtasklet_info;

  rwdtsperf_config_init(instance);

  // Return the allocated instance
  return instance;
}
Example #7
0
RwTaskletPluginComponentHandle *
rwlogd__component__component_init(RwTaskletPluginComponent *self)
{
  rwlogd_component_ptr_t component;
  RwTaskletPluginComponentHandle *h_component;
  gpointer handle;

  // Register the RW.Init types
  RW_CF_TYPE_REGISTER(rwlogd_component_ptr_t);
  RW_CF_TYPE_REGISTER(rwlogd_instance_ptr_t);

  // Allocate a new rwlogd_component structure
  component = RW_CF_TYPE_MALLOC0(sizeof(*component), rwlogd_component_ptr_t);
  RW_CF_TYPE_VALIDATE(component, rwlogd_component_ptr_t);

  // Allocate a gobject for the handle
  handle = g_object_new(RW_TASKLET_PLUGIN_TYPE_COMPONENT_HANDLE, 0);
  h_component = RW_TASKLET_PLUGIN_COMPONENT_HANDLE(handle);
  h_component->priv = (gpointer) component;

  // Return the handle to the rwtasklet component
  return h_component;
}
Example #8
0
CF_EXPORT rwsched_CFRunLoopTimerRef
rwsched_tasklet_CFRunLoopTimerCreate(rwsched_tasklet_ptr_t sched_tasklet,
                                     CFAllocatorRef allocator,
                                     CFAbsoluteTime fireDate,
                                     CFTimeInterval interval,
                                     CFOptionFlags flags,
                                     CFIndex order,
                                     rwsched_CFRunLoopTimerCallBack callout,
                                     rwsched_CFRunLoopTimerContext *context)
{
    // Validate input parameters
    RW_CF_TYPE_VALIDATE(sched_tasklet, rwsched_tasklet_ptr_t);
    rwsched_instance_ptr_t instance = sched_tasklet->instance;
    RW_CF_TYPE_VALIDATE(instance, rwsched_instance_ptr_t);

    rwsched_CFRunLoopTimerRef rwsched_timer;
    unsigned int i;

    RW_ASSERT(context->info);

    // Allocate a rwsched container type and track it
    rwsched_timer = RW_CF_TYPE_MALLOC0(sizeof(*rwsched_timer), rwsched_CFRunLoopTimerRef);

    // Look for an unused entry in cftimer_array (start the indexes at 1 for now)
    //RW_GOBJECT_TYPE_VALIDATE(sched_tasklet->cftimer_array, GArray);
    for (i = 1 ; i < sched_tasklet->cftimer_array->len ; i++) {
        if (g_array_index(sched_tasklet->cftimer_array, rwsched_CFRunLoopTimerRef, i) == NULL) {
            g_array_index(sched_tasklet->cftimer_array, rwsched_CFRunLoopTimerRef, i) = rwsched_timer;
            break;
        }
    }
    if (i >= sched_tasklet->cftimer_array->len) {
        // Insert a new element at the end of the array
        g_array_append_val(sched_tasklet->cftimer_array, rwsched_timer);
    }

    // Mark the rwsched_timer as in use
    RW_CF_TYPE_VALIDATE(rwsched_timer, rwsched_CFRunLoopTimerRef);
    rwsched_timer->index = i;

    if (interval == 0) {
        rwsched_timer->onetime_timer = 1;
        rwsched_timer->ott.allocator = allocator;
        rwsched_timer->ott.flags = flags;
        rwsched_timer->ott.order = order;
    }

    // Call the native CFRunLoop function
    if (context && context->info == NULL) {
        context->info = rwsched_timer;
    }
    rwsched_timer->tmp_context = *context;
    rwsched_timer->tmp_context.info = rwsched_timer;
    rwsched_timer->cf_callout = callout;
    rwsched_tasklet_ref(sched_tasklet);
    rwsched_timer->callback_context.tasklet_info = sched_tasklet;
    rwsched_instance_ref(instance);
    rwsched_timer->callback_context.instance = instance;
    rwsched_timer->cf_object = CFRunLoopTimerCreate(allocator,
                               fireDate,
                               interval,
                               flags,
                               order,
                               rwsched_cftimer_callout_intercept,
                               &rwsched_timer->tmp_context);
    rwsched_timer->cf_context = *context;

    // Return the rwsched container type
    return rwsched_timer;
}
Example #9
0
rwsched_instance_t *
rwsched_instance_new(void)
{
  struct rwsched_instance_s *instance;

  // Allocate memory for the new instance

  // Register the rwsched instance types
  RW_CF_TYPE_REGISTER(rwsched_instance_ptr_t);
  RW_CF_TYPE_REGISTER(rwsched_tasklet_ptr_t);
  rwsched_CFRunLoopInit();
  rwsched_CFSocketInit();

  // Allocate the Master Resource-Tracking Handle
  g_rwresource_track_handle = RW_RESOURCE_TRACK_CREATE_CONTEXT("The Master Context");

  // Allocate a rwsched instance type and track it
  instance = RW_CF_TYPE_MALLOC0(sizeof(*instance), rwsched_instance_ptr_t);
  RW_CF_TYPE_VALIDATE(instance, rwsched_instance_ptr_t);

  // Set the instance configuration
  instance->config.single_thread = TRUE;

  // For now use libdispatch only
  instance->use_libdispatch_only = TRUE;
  // libdispatch_init();

  // Fake up a rwqueue placeholder object to use as the (NULL) DISPATCH_TARGET_QUEUE_DEFAULT
  RW_ASSERT(instance->use_libdispatch_only);
  instance->default_rwqueue = (rwsched_dispatch_queue_t) RW_MALLOC0_TYPE(sizeof(*instance->default_rwqueue), rwsched_dispatch_queue_t);
  RW_ASSERT_TYPE(instance->default_rwqueue, rwsched_dispatch_queue_t);
  instance->default_rwqueue->header.libdispatch_object._dq = DISPATCH_TARGET_QUEUE_DEFAULT;

  // Fake up a rwqueue placeholder object to use as DISPATCH_TARGET_QUEUE_MAIN
  RW_ASSERT(instance->use_libdispatch_only);
  instance->main_rwqueue = (rwsched_dispatch_queue_t) RW_MALLOC0_TYPE(sizeof(*instance->main_rwqueue), rwsched_dispatch_queue_t);
  RW_ASSERT_TYPE(instance->main_rwqueue, rwsched_dispatch_queue_t);
  instance->main_rwqueue->header.libdispatch_object._dq = dispatch_get_main_queue();

  // Fake up rwqueue placeholder objects for the usual four global
  // queues.  The pri values are not 0,1,2,3 or similar, they are
  // -MAX, -2, 0, 2.  We do not support arbitrary pri values, although
  // I think the dispatch API is intended to.
  RW_ASSERT(instance->use_libdispatch_only);
  RW_STATIC_ASSERT(RWSCHED_DISPATCH_QUEUE_GLOBAL_CT == 4);
  static long pris[RWSCHED_DISPATCH_QUEUE_GLOBAL_CT] = {
    DISPATCH_QUEUE_PRIORITY_HIGH,
    DISPATCH_QUEUE_PRIORITY_DEFAULT,
    DISPATCH_QUEUE_PRIORITY_LOW,
    DISPATCH_QUEUE_PRIORITY_BACKGROUND
  };
  int  i; for (i=0; i<RWSCHED_DISPATCH_QUEUE_GLOBAL_CT; i++) {
    instance->global_rwqueue[i].pri = pris[i];
    instance->global_rwqueue[i].rwq = (rwsched_dispatch_queue_t) RW_MALLOC0_TYPE(sizeof(*instance->global_rwqueue[i].rwq), rwsched_dispatch_queue_t);
    RW_ASSERT_TYPE(instance->global_rwqueue[i].rwq, rwsched_dispatch_queue_t);
    instance->global_rwqueue[i].rwq->header.libdispatch_object._dq = dispatch_get_global_queue(pris[i], 0);
    RW_ASSERT(instance->global_rwqueue[i].rwq->header.libdispatch_object._dq);
  }

  instance->main_cfrunloop_mode = kCFRunLoopDefaultMode;
  //instance->main_cfrunloop_mode = CFSTR("TimerMode");
  //instance->deferred_cfrunloop_mode = CFSTR("Deferred Mode");

  // Allocate an array of tasklet pointers and track it
  rwsched_tasklet_t *tasklet = NULL;
  instance->tasklet_array = g_array_sized_new(TRUE, TRUE, sizeof(void *), 256);
  g_array_append_val(instance->tasklet_array, tasklet);

  rwsched_instance_ref(instance);
  ck_pr_inc_32(&g_rwsched_instance_count);
  //RW_ASSERT(g_rwsched_instance_count <= 2);
  g_rwsched_instance = instance;

  instance->rwlog_instance = rwlog_init("RW.Sched");

  // Return the instance pointer
  return instance;
}
Example #10
0
uint64_t
rwmsg_toyfd_add(rwmsg_toytask_t *toy, int fd, int pollbits, toyfd_cb_t cb, void *ud)
{
  rwsched_instance_ptr_t instance;
  rwmsg_toytask_t *toytask = toy;
  //rwsched_dispatch_source_t source;
  struct rwmsg_toyfd_s *toyfd;

  // Validate input parameters
  RW_CF_TYPE_VALIDATE(toytask, rwtoytask_tasklet_ptr_t);

  // Get the rwsched instance from the toytask
  instance = toytask->toysched->rwsched_instance;
  RW_CF_TYPE_VALIDATE(instance, rwsched_instance_ptr_t);

  // Allocate a toyfd container type and track it
  toyfd = RW_CF_TYPE_MALLOC0(sizeof(*toyfd), rwmsg_toyfd_ptr_t);
  RW_CF_TYPE_VALIDATE(toyfd, rwmsg_toyfd_ptr_t);
  
  // Example of using CFSocket to manage file descriptors on a runloop using CFStreamCreatePairWithSocket()
  // http://lists.apple.com/archives/macnetworkprog/2003/Jul/msg00075.html
  CFSocketContext cf_context = { 0, NULL, NULL, NULL, NULL };
  CFOptionFlags cf_callback_flags = 0;
  CFOptionFlags cf_option_flags = 0;
  rwsched_CFRunLoopRef runloop = rwsched_tasklet_CFRunLoopGetCurrent(toytask->rwsched_tasklet_info);
  rwsched_CFSocketRef cfsocket;
  rwsched_CFRunLoopSourceRef cfsource;

  // Use the pollbits to determine which socket callback events to register
  if (pollbits & POLLIN) {
    cf_callback_flags |= kCFSocketReadCallBack;
    cf_option_flags |= kCFSocketAutomaticallyReenableReadCallBack;
  }
  if (pollbits & POLLOUT) {
    cf_callback_flags |= kCFSocketWriteCallBack;
    cf_option_flags |= kCFSocketAutomaticallyReenableWriteCallBack;
  }

  // Create a CFSocket as a runloop source for the toyfd file descriptor
  cf_context.info = toyfd;
  cfsocket = rwsched_tasklet_CFSocketCreateWithNative(toytask->rwsched_tasklet_info,
					      kCFAllocatorSystemDefault,
					      fd,
					      cf_callback_flags,
					      rwmsg_toysched_io_callback,
					      &cf_context);
  RW_CF_TYPE_VALIDATE(cfsocket, rwsched_CFSocketRef);
  rwsched_tasklet_CFSocketSetSocketFlags(toytask->rwsched_tasklet_info, cfsocket, cf_option_flags);
  cfsource = rwsched_tasklet_CFSocketCreateRunLoopSource(toytask->rwsched_tasklet_info,
						 kCFAllocatorSystemDefault,
						 cfsocket,
						 0);
  RW_CF_TYPE_VALIDATE(cfsource, rwsched_CFRunLoopSourceRef);
  rwsched_tasklet_CFRunLoopAddSource(toytask->rwsched_tasklet_info, runloop, cfsource, instance->main_cfrunloop_mode);

  // Fill in the toyfd structure
  toyfd->cf_ref = cfsocket;
  toyfd->id = cfsocket->index;
  toyfd->fd = fd;
  toyfd->cb = cb;
  toyfd->ud = ud;
  toyfd->toytask = toytask;

  // Fill in the read context structure
  if (pollbits & POLLIN) {
    toyfd->read_context.source.cfsource = cfsource;
  }

  // Fill in the write context structure
  if (pollbits & POLLOUT) {
    toyfd->write_context.source.cfsource = cfsource;
  }

  // Return the callback id
  return (uint64_t) toyfd->id;
}