Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #5949

Re: Reference counting

From Shao Miller <sha0.miller@gmail.com>
Newsgroups comp.lang.c
Subject Re: Reference counting
Date 2011-06-12 21:13 -0500
Organization A noiseless patient Spider
Message-ID <it3roq$ear$1@dont-email.me> (permalink)
References (1 earlier) <e9ef06c1-e30d-4953-8f15-d72b2bdde0eb@k17g2000vbn.googlegroups.com> <isulh0$ipq$1@dont-email.me> <52c902de-0f66-4bb0-b787-8c440c2405db@hg8g2000vbb.googlegroups.com> <it0mco$bl7$1@dont-email.me> <d677e296-f284-4fef-9d3a-3a119da4ea7c@d1g2000yqe.googlegroups.com>

Show all headers | View raw


On 6/12/2011 5:15 PM, luser- -droog wrote:
> On Jun 11, 5:23 pm, Shao Miller<sha0.mil...@gmail.com>  wrote:
>> On 6/11/2011 2:36 PM, ImpalerCore wrote:
>>
>>> If I understand correctly, malloc should always return an aligned
>>> pointer, so by knowing ALIGN_MAX, the pointer at offset ALIGN_MAX
>>> should also be suitably aligned for any other object.  I think this
>>> might work, but I hesitate as the nuances of alignment issues continue
>>> to elude my understanding.
>>
>> Or you can put your accounting object at/near the end of the allocated
>> memory, as mentioned else-thread.  Would anyone else mind mentioning
>> this or does nobody really do that?  I thought it was fairly common
>> practice for some I/O buffers.  Filtering... *sigh*
>
> With a suitable convention established for finding the end, sure.
> But the simplest way to find the end is to put a size field or
> pointer at the beginning, and we're back to the same alignment
> question. So it's hard to explore that option without making the
> entire issue more complicated.

I agree that a disadvantage to accounting at the end is the convention 
for finding the end.

The example code offered elsethread has a function that takes a 'size_t' 
which must match what was passed to the allocator, and passing this 
around is certainly overhead.

For a simple string-accounting struct which keeps track of the size, one 
can pass 'sizeof *my_string + my_string->max_length' (or whatever), but 
you're right; that seems like an awkward thing to pass to a 
reference-releasing function.

For statically-sized objects, a macro makes things a bit easier (note 
that 'ptr' is only evaluated once, for whatever that's worth):

   #define release(ptr) (release_((ptr), sizeof *(ptr)))

Here's a code example, below.  It ought to compile as one file.  If 
anyone has time to review it, what're some advantages and disadvantages 
for the approach?:

   #define ALL_IN_ONE 1


   /**** ref_cnt.h */

   /* For 'size_t' */
   #include <stddef.h>

   /*** Macros */
   #define GetRefForFixedSizeObj(obj) \
     (GetRefFromPtrAndSize((obj), sizeof *(obj)))

   /*** Object types */
   typedef void ** ref_counted_obj;

   /*** Function types */
   typedef void f_ref_cnt_free(ref_counted_obj);

   /*** Functions */
   extern ref_counted_obj GetRefFromPtrAndSize(void *, size_t);
   extern ref_counted_obj NewRefCountedObj(size_t, f_ref_cnt_free *);
   extern ref_counted_obj GetRef(ref_counted_obj);
   extern void PutRef(ref_counted_obj);


   /**** ref_cnt.c */

   #include <stdlib.h>
   #if !ALL_IN_ONE
   #include <stddef.h>
   #include "ref_cnt.h"
   #endif

   /*** Types */
   struct ref_counted_obj_ {
       void * obj;
       unsigned int ref_count;
       f_ref_cnt_free * dealloc;
     };

   /*** Functions */

   static ptrdiff_t ref_at(size_t size) {
       size_t result;

       result = size;
       result += sizeof (struct ref_counted_obj_);
       /* Check for wrap-around */
       if (result < size)
         return 0;
       --result;
       result /= sizeof (struct ref_counted_obj_);
       return (ptrdiff_t) result;
     }

   ref_counted_obj GetRefFromPtrAndSize(
       void * ptr,
       size_t size
     ) {
       ptrdiff_t ref_index;
       struct ref_counted_obj_ * ref;

       ref_index = ref_at(size);
       if (!ptr || !ref_index)
         return NULL;
       /* Point to the accounting info */
       ref = ptr;
       ref += ref_index;
       /* Increment ref count and check for wrap-around */
       if (!++ref->ref_count) {
           --ref->ref_count;
           return NULL;
         }
       return &ref->obj;
     }

   ref_counted_obj NewRefCountedObj(
       size_t size,
       f_ref_cnt_free * dealloc
     ) {
       ptrdiff_t ref_index;
       size_t new_size;
       struct ref_counted_obj_ * ref;

       ref_index = ref_at(size);
       if (!ref_index)
         return NULL;
       /* Calculate required size */
       new_size = (ref_index + 1) * sizeof *ref;
       /* Check for wrap-around */
       if (new_size < size)
         return NULL;
       /* Allocate and check for failure */
       ref = malloc(new_size);
       if (!ref)
         return NULL;
       /* Populate accounting info */
       ref[ref_index].obj = ref;
       ref += ref_index;
       ref->ref_count = 1;
       ref->dealloc = dealloc;
       return &ref->obj;
     }

   ref_counted_obj GetRef(ref_counted_obj ref) {
       struct ref_counted_obj_ * ref_;

       if (!ref)
         return NULL;
       ref_ = (void *) ref;
       /* Increment ref count and check for wrap-around */
       if (++ref_->ref_count) {
           --ref_->ref_count;
           return NULL;
         }
       return ref;
     }

   void PutRef(ref_counted_obj ref) {
       struct ref_counted_obj_ * ref_;

       if (!ref)
         return;
       ref_ = (void *) ref;
       /* Decrement ref count and check for zero */
       if (!--ref_->ref_count) {
           ref_->dealloc(ref);
           free(ref_->obj);
         }
       return;
     }


   /**** Test program */

   #include <stdio.h>
   #include <string.h>
   #if !ALL_IN_ONE
   #include <stdlib.h>
   #include "ref_cnt.h"
   #endif

   /*** Macros */
   #define GetFooRef(foo) \
     (GetRefFromPtrAndSize((foo), sizeof *(foo) + (foo)->len))

   /*** Types */
   struct foo {
       double bobble;
       size_t len;
       char bear[1];
     };

   /*** Functions */
   f_ref_cnt_free foo_dealloc;
   void foo_dealloc(ref_counted_obj ptr) {
       struct foo * bar;

       bar = *ptr;
       printf(
           "foo_dealloc(%p): {%f, %d, \"%s\"}\n",
           *ptr,
           bar->bobble,
           (int)bar->len,
           bar->bear
         );
       return;
     }

   int main(void) {
       ref_counted_obj bar_ref;
       struct foo * bar;
       char laughsalot[] = "Laughs-a-lot";

       bar_ref = NewRefCountedObj(
           sizeof *bar + sizeof laughsalot,
           foo_dealloc
         );
       if (!bar_ref) {
           puts("NewRefCountedObj() failed!");
           return EXIT_FAILURE;
         }

       bar = *bar_ref;
       bar->bobble = 3.14159;
       bar->len = sizeof laughsalot;
       memcpy(bar->bear, laughsalot, sizeof laughsalot);

       /* Test re-getting the accounting info */
       bar_ref = NULL;
       bar_ref = GetFooRef(bar);
       if (!bar_ref) {
           puts("GetRefFromPtrAndSize() failed!");
           free(bar);  /* Yeah */
           return EXIT_FAILURE;
         }

       /* We have two references */
       PutRef(bar_ref);
       PutRef(bar_ref);
       return EXIT_SUCCESS;
     }

Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Reference counting daknok <radekslupik@gmail.com> - 2011-06-05 12:52 +0200
  Re: Reference counting Angel <angel+news@spamcop.net> - 2011-06-05 11:17 +0000
    Re: Reference counting Gene <gene.ressler@gmail.com> - 2011-06-06 20:07 -0700
      Multiple Inheritance (Was Re: Reference counting) Shao Miller <sha0.miller@gmail.com> - 2011-06-11 03:57 -0500
        Re: Multiple Inheritance (Was Re: Reference counting) Dr Nick <3-nospam@temporary-address.org.uk> - 2011-06-12 07:22 +0100
  Re: Reference counting China Blue Angels <chine.bleu@yahoo.com> - 2011-06-05 05:07 -0700
  Re: Reference counting "BartC" <bc@freeuk.com> - 2011-06-05 13:14 +0100
    Re: Reference counting daknok <daknok@example.com> - 2011-06-05 14:22 +0200
      Re: Reference counting "BartC" <bc@freeuk.com> - 2011-06-05 14:45 +0100
        Re: Reference counting daknok <daknok@example.com> - 2011-06-05 17:01 +0200
          Re: Reference counting Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-06-05 18:06 -0400
          Re: Reference counting Dr Nick <3-nospam@temporary-address.org.uk> - 2011-06-12 07:25 +0100
  Re: Reference counting daknok <daknok@example.com> - 2011-06-05 15:29 +0200
  Re: Reference counting Shao Miller <sha0.miller@gmail.com> - 2011-06-05 12:17 -0500
  Re: Reference counting cri@tiac.net (Richard Harter) - 2011-06-05 17:11 +0000
  Re: Reference counting ImpalerCore <jadill33@gmail.com> - 2011-06-10 11:30 -0700
    Re: Reference counting Shao Miller <sha0.miller@gmail.com> - 2011-06-10 16:04 -0400
    Re: Reference counting James Kuyper <jameskuyper@verizon.net> - 2011-06-10 22:56 -0400
      Re: Reference counting ImpalerCore <jadill33@gmail.com> - 2011-06-11 12:36 -0700
        Re: Reference counting Shao Miller <sha0.miller@gmail.com> - 2011-06-11 17:23 -0500
          Re: Reference counting luser- -droog <mijoryx@yahoo.com> - 2011-06-12 15:15 -0700
            Re: Reference counting Shao Miller <sha0.miller@gmail.com> - 2011-06-12 21:13 -0500
              Re: Reference counting "Chris M. Thomasson" <cristom@charter.net> - 2011-06-13 12:37 -0700
                Re: Reference counting "Chris M. Thomasson" <cristom@charter.net> - 2011-06-13 12:54 -0700
                Re: Reference counting Shao Miller <sha0.miller@gmail.com> - 2011-06-13 16:40 -0500
          Re: Reference counting ImpalerCore <jadill33@gmail.com> - 2011-06-13 07:34 -0700
            Re: Reference counting Shao Miller <sha0.miller@gmail.com> - 2011-06-13 14:26 -0500
              Re: Reference counting ImpalerCore <jadill33@gmail.com> - 2011-06-13 12:47 -0700
                Re: Reference counting Shao Miller <sha0.miller@gmail.com> - 2011-06-13 17:33 -0500
                Re: Reference counting ImpalerCore <jadill33@gmail.com> - 2011-06-14 12:14 -0700
                Re: Reference counting Shao Miller <sha0.miller@gmail.com> - 2011-06-15 02:16 -0500
                Re: Reference counting "Chris M. Thomasson" <cristom@charter.net> - 2011-06-15 15:34 -0700
                Re: Reference counting "Chris M. Thomasson" <cristom@charter.net> - 2011-06-15 15:42 -0700
                Re: Reference counting "Chris M. Thomasson" <cristom@charter.net> - 2011-06-16 13:45 -0700
                Re: Reference counting Shao Miller <sha0.miller@gmail.com> - 2011-06-16 17:02 -0500
                Re: Reference counting "Chris M. Thomasson" <cristom@charter.net> - 2011-06-16 15:18 -0700
                Re: Reference counting "Chris M. Thomasson" <cristom@charter.net> - 2011-06-16 16:01 -0700
                Re: Reference counting Shao Miller <sha0.miller@gmail.com> - 2011-06-16 18:44 -0500
                Re: Reference counting "Chris M. Thomasson" <cristom@charter.net> - 2011-06-16 17:11 -0700
                Re: Reference counting Shao Miller <sha0.miller@gmail.com> - 2011-06-16 18:39 -0500
        Re: Reference counting "Chris M. Thomasson" <cristom@charter.net> - 2011-06-11 16:51 -0700
          Re: Reference counting "Chris M. Thomasson" <cristom@charter.net> - 2011-06-11 18:28 -0700
            Re: Reference counting Shao Miller <sha0.miller@gmail.com> - 2011-06-12 16:10 -0500
            Re: Reference counting ImpalerCore <jadill33@gmail.com> - 2011-06-13 07:36 -0700
      Re: Reference counting Tim Rentsch <txr@alumni.caltech.edu> - 2011-06-14 15:00 -0700
  Re: Reference counting luser- -droog <mijoryx@yahoo.com> - 2011-06-13 21:46 -0700
    Re: Reference counting Shao Miller <sha0.miller@gmail.com> - 2011-06-14 03:19 -0500
      Re: Reference counting Angel <angel+news@spamcop.net> - 2011-06-14 07:31 +0000
        Re: Reference counting Shao Miller <sha0.miller@gmail.com> - 2011-06-14 05:02 -0500
        Re: Reference counting Keith Thompson <kst-u@mib.org> - 2011-06-14 09:03 -0700
          Re: Reference counting luser- -droog <mijoryx@yahoo.com> - 2011-06-14 10:23 -0700
            Re: Reference counting Shao Miller <sha0.miller@gmail.com> - 2011-06-14 13:46 -0500
          Re: Reference counting Tim Rentsch <txr@alumni.caltech.edu> - 2011-06-14 15:05 -0700
            Re: Reference counting Keith Thompson <kst-u@mib.org> - 2011-06-14 16:44 -0700
              Re: Reference counting Tim Rentsch <txr@alumni.caltech.edu> - 2011-06-15 06:54 -0700
                Re: Reference counting Keith Thompson <kst-u@mib.org> - 2011-06-15 08:46 -0700
                Re: Reference counting pete <pfiland@mindspring.com> - 2011-06-15 22:19 -0400
                Re: Reference counting James Kuyper <jameskuyper@verizon.net> - 2011-06-15 23:03 -0400
                Re: Reference counting Tim Rentsch <txr@alumni.caltech.edu> - 2011-06-19 14:48 -0700
        Re: Reference counting Seebs <usenet-nospam@seebs.net> - 2011-06-14 17:16 +0000
    Re: Reference counting luser- -droog <mijoryx@yahoo.com> - 2011-06-14 20:53 -0700
      Re: Reference counting Shao Miller <sha0.miller@gmail.com> - 2011-06-16 18:49 -0500
  Re: Reference counting "io_x" <a@b.c.invalid> - 2011-06-14 08:30 +0200
    Re: Reference counting "io_x" <a@b.c.invalid> - 2011-06-14 09:15 +0200
      Re: Reference counting Shao Miller <sha0.miller@gmail.com> - 2011-06-14 04:21 -0500
      Re: Reference counting "io_x" <a@b.c.invalid> - 2011-06-16 10:35 +0200
        Re: Reference counting Ian Collins <ian-news@hotmail.com> - 2011-06-16 20:36 +1200
        Re: Reference counting "io_x" <a@b.c.invalid> - 2011-06-16 11:21 +0200
          Re: Reference counting "io_x" <a@b.c.invalid> - 2011-06-19 17:57 +0200
          Re: Reference counting "io_x" <a@b.c.invalid> - 2011-06-19 20:01 +0200
            Re: Reference counting Keith Thompson <kst-u@mib.org> - 2011-06-19 11:07 -0700
            Re: Reference counting Shao Miller <sha0.miller@gmail.com> - 2011-06-19 23:15 -0500
              Re: Reference counting "io_x" <a@b.c.invalid> - 2011-06-20 08:21 +0200
        Re: Reference counting Shao Miller <sha0.miller@gmail.com> - 2011-06-16 19:05 -0500
          Re: Reference counting Ian Collins <ian-news@hotmail.com> - 2011-06-17 12:09 +1200
  Re: Reference counting luser- -droog <mijoryx@yahoo.com> - 2011-06-15 08:40 -0700
  Re: Reference counting "christian.bau" <christian.bau@cbau.wanadoo.co.uk> - 2011-06-16 11:08 -0700
    Re: Reference counting Shao Miller <sha0.miller@gmail.com> - 2011-06-16 14:42 -0400

csiph-web