Shop OBEX P1 Docs P2 Docs Learn Events
C: Solution Needed — Parallax Forums

C: Solution Needed

idbruceidbruce Posts: 6,197
edited 2015-04-09 12:30 in Propeller 1
This quote is taken from the Learn C tutorials:
The Functions lesson Memory Functions Can Share showed you how to make functions share information with global variables instead of with parameters. Code running in different cogs can use this technique to exchange information as well. There’s just one extra detail: when you declare global variables for cores to share, you have to precede each one with the keyword volatile. So instead of int globalVar, the declaration would be volatile int globalVar.
Source: http://learn.parallax.com/multicore-approaches/cores-sharing-data

This presents a problem for copying data, instead of sharing it, such as with the use of memcpy. It would be nice if we had a gcc compatible volatile_memcpy function for use with the Propeller. And perhaps one that could later be added to SimpleIDE for those that may require such a function. I came across this, but they left out the important part, which is most likely GCC specific:
size_t volatile_memcpy(volatile void *d, volatile void *s, size_t n)
{
   code here
}

but from what I have seen, it should probably be more like this:
void * volatile_memcpy(volatile void *d, volatile void *s, size_t n)
{
   code here
}
«1

Comments

  • Heater.Heater. Posts: 21,230
    edited 2015-04-08 15:03
    You worry too much.

    Forget memcpy() just use:
    while (n--) *s2++ = *s1++;
    
    And define the types of n, s1 and s2 as you like.

    Job done.
  • pmrobertpmrobert Posts: 673
    edited 2015-04-08 15:32
    Heater. wrote: »
    You worry too much.

    Forget memcpy() just use:
    while (n--) *s2++ = *s1++;
    
    And define the types of n, s1 and s2 as you like.

    Job done.

    Simple yet elegant. Awesomely cool!
  • idbruceidbruce Posts: 6,197
    edited 2015-04-08 15:37
    Heater
    You worry too much.

    I once was carefree, ahhh those were the days :)
    Forget memcpy() just use:
    while (n--) *s2++ = *s1++;And define the types of n, s1 and s2 as you like. 
    

    Job done.

    I suppose n would be sizeof.....

    Would this work? while(sizeof(SOURCE)--) *d++ = *s++;
  • ElectrodudeElectrodude Posts: 1,658
    edited 2015-04-08 16:22
    idbruce wrote: »
    I suppose n would be sizeof.....

    Would this work? while(sizeof(SOURCE)--) *d++ = *s++;
    I doubt it, but I didn't try. You can't decrement a constant expression. Just put it in a temporary variable:
    size_t n = sizeof(SOURCE);
    while (n--) *d++ = *s++;
    
  • idbruceidbruce Posts: 6,197
    edited 2015-04-08 17:54
    Thanks Electrodude
  • Heater.Heater. Posts: 21,230
    edited 2015-04-08 20:45
    Be sure to make your source and destination pointers char *.
  • idbruceidbruce Posts: 6,197
    edited 2015-04-09 04:54
    Heater
    And define the types of n, s1 and s2 as you like.
    Be sure to make your source and destination pointers char *.

    There now appears to be a contradiction and it now appears to be a string copy. What about copying an entire struct?

    During my research of memcpy, I came across two definitions, one from Microsoft and the other from Apple. Both of these definitions had conditions for copy forward or backward, based upon the data types. And both of these definitions were certainly a lot more complicated than a one liner.
  • Heater.Heater. Posts: 21,230
    edited 2015-04-09 05:15
    OK, what do you actually want to do:

    1) Copy a string?
    2) Copy some other area of memory?
    3) Copy a struct?

    memcpy is the same no matter where it's defined. For example for OSX
    NAME
         memcpy -- copy memory area
    
    LIBRARY
         Standard C Library (libc, -lc)
    
    SYNOPSIS
         #include <string.h>
    
         void *
         memcpy(void *restrict dst, const void *restrict src, size_t n);
    
    DESCRIPTION
         The memcpy() function copies n bytes from memory area src to memory area dst.  If dst and src overlap,
         behavior is undefined.  Applications in which dst and src might overlap should use memmove(3) instead.
    
    RETURN VALUES
         The memcpy() function returns the original value of dst.
    
    SEE ALSO
         bcopy(3), memccpy(3), memmove(3), strcpy(3), wmemcpy(3)
    
    STANDARDS
         The memcpy() function conforms to ISO/IEC 9899:1990 (``ISO C90'').
    
    Note the memcpy does not like overlapping memory areas.
  • idbruceidbruce Posts: 6,197
    edited 2015-04-09 05:31
    Heater
    OK, what do you actually want to do:

    1) Copy a string?
    2) Copy some other area of memory?
    3) Copy a struct?

    The point of my post was to enable copying of data from one cog to another in a standard tradition that memcpy can be used without cogs. So in other words, I want to be able to:

    1) Copy a string
    2) Copy some other area of memory
    3) Copy a struct
  • Heater.Heater. Posts: 21,230
    edited 2015-04-09 05:43
    I don't understand what is wrong with using:

    1) strcpy or strncpy
    2) memcpy or memmove
    3) Simply assigning structs: a = b; where a and b are the same struct type.
  • idbruceidbruce Posts: 6,197
    edited 2015-04-09 05:52
    Unless Parallax documentation is wrong and specific to #2 of your last post, volatile is discarded by memcpy. Again the point of my post.
  • trancefreaktrancefreak Posts: 186
    edited 2015-04-09 06:02
    Hi Bruce,

    I think you misunderstood that. The volatile keyword is used to prevent the compiler from optimizing the variable/struct away.
    This sometimes can happen if your main program just sets values to a variable and a COG program reads them and does it's job depending on the value.

    The compiler will see, that the main program just sets values but never uses them and optimizes the variable away which is not good because then the COG program never gets something to do.

    A memcpy should never be optimized away...
  • Heater.Heater. Posts: 21,230
    edited 2015-04-09 06:04
    volatile may well be discarded by memcpy. So what? I don't see how that can cause it to fail.

    It it worries you that memcpy may fail then just use the solution in post #2.
  • idbruceidbruce Posts: 6,197
    edited 2015-04-09 06:22
    Heater, I believe you like to argue just to show how smart you are. Not everyone is as program language savy as you are. memcpy is a handy feature and the use of it with volatile data spits numerous warnings. Even if it didn't fail, it would make the compiling look like that of a child.

    You like work arounds. I like to have working functions at my disposal that don't generate warnings.

    Let's see, if you want to copy a string, you must do it this way, if you want to copy a struct, you must do it this way, if you want to copy other memory, you must do it this way.
  • Heater.Heater. Posts: 21,230
    edited 2015-04-09 06:41
    idbruce,
    I believe you like to argue just to show how smart you are.
    If that is your attitude I may not be so inclined to offer help in future. I will ignore that unnecessary slur for now.
    Even if it didn't fail, it would make the compiling look like that of a child.
    Those warnings can be removed by the correct use of casts when calling memcpy.
    I like to have working functions at my disposal that don't generate warnings.
    Not an unreasonable expectation. Except...
    ...if you want to copy a string, you must do it this way, if you want to copy a struct, you must do it this way, if you want to copy other memory, you must do it this way.
    Unfortunately that is how it is. In C it is impossible to create a single function, say copy(a, b), that will copy any type of thing. Strings, memory blocks, structs etc are all different types and require different copy mechanisms.
  • idbruceidbruce Posts: 6,197
    edited 2015-04-09 06:49
    post deleted
  • DavidZemonDavidZemon Posts: 2,973
    edited 2015-04-09 06:50
    Maybe we can get this back on track...
    idbruce wrote: »
    There now appears to be a contradiction and it now appears to be a string copy. What about copying an entire struct?

    Most compilers define "char" as "int8_t". In other words, it's just an 8-bit, signed variable. It doesn't matter that the name is "char". Because of this exact confusion, I much prefer the use of uint8_t, int8_t, uint16_t, int16_t, uint32_t and int32_t instead of their english counterparts.

    It might look like a string copy, but all you're doing is copying byte-by-byte, which is exactly what you want.
  • idbruceidbruce Posts: 6,197
    edited 2015-04-09 07:05
    @Heater and SwimDude
    Most compilers define "char" as "int8_t".

    Yes, this I know, but I am unfamiliar with how the memcpy for GCC is implemented. Is it always a byte for byte copy?

    In my current endeavors, I am working a lot with structs, where either the whole struct will be copied or just parts of it, with varying types of data, and often these structs will be in different cogs.
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-04-09 07:12
    Bruce, can you delete post #17. I find it very offensive.
  • Dave HeinDave Hein Posts: 6,347
    edited 2015-04-09 07:14
    Most compilers define "char" as "int8_t". In other words, it's just an 8-bit, signed variable. It doesn't matter that the name is "char".
    The char type in PropGCC is unsigned.
  • PublisonPublison Posts: 12,366
    edited 2015-04-09 07:19
    Dave Hein wrote: »
    Bruce, can you delete post #17. I find it very offensive.

    Probably a good idea. :)
  • idbruceidbruce Posts: 6,197
    edited 2015-04-09 07:28
    Post deleted. Might as well delete the whole thread..... Everytime I recommend something... Someone always shoots the idea down... I don't know why I waste my thoughts
  • DavidZemonDavidZemon Posts: 2,973
    edited 2015-04-09 07:40
    idbruce wrote: »
    Post deleted. Might as well delete the whole thread..... Everytime I recommend something... Someone always shoots the idea down... I don't know why I waste my thoughts

    This forum has it's ups and downs but it's a lot better than most of the Internet. Just remember that. :)
    idbruce wrote: »
    @Heater and SwimDude



    Yes, this I know, but I am unfamiliar with how the memcpy for GCC is implemented. Is it always a byte for byte copy?

    In my current endeavors, I am working a lot with structs, where either the whole struct will be copied or just parts of it, with varying types of data, and often these structs will be in different cogs.

    To fully answer your question, here ya go! https://github.com/totalspectrum/proplib/blob/e54fd9572c80619ef6a85a13f66391cbef7b9c51/string/memcpy.c

    To directly and simply answer your question, it does byte-by-byte some of the time. If the variables are both word-aligned, it does word-by-word. Pretty cool actually... I wouldn't have thought of that.
  • idbruceidbruce Posts: 6,197
    edited 2015-04-09 07:51
    This forum has it's ups and downs but it's a lot better than most of the Internet. Just remember that.

    Yea David, but there are some on here that get away with a lot more than others. Preferential treatment.

    The first response was "You worry too much"..... Is that a helpful phrase? I think not..... but instead I did my best to let it roll off.....
    First word was "YOU".... Did a compliment follow? No, instead it was something derogatory.
  • User NameUser Name Posts: 1,451
    edited 2015-04-09 08:30
    At some time or another, we've all worried to much about something. It's a great thing, imho, to have an expert tell me I needn't worry. Sometimes I wish documentation showed us how little we need to worry, not how much. :)
  • Heater.Heater. Posts: 21,230
    edited 2015-04-09 08:36
    idbruce,

    Ah I see. I did not notice that "You worry to much" could be taken as condescending, which of course it can be. Certainly not my intention.

    Hey, you deleted the "He needs a hangin' " post. I quite enjoyed that little joke.

    Any resemblance between my behaviour and intelligence, real or fictional, is purely coincidental.

    As for preferential treatment, well I have been warned to keep myself in check on occasion, always with good reason.

    As for memcpy, the contract is that n contiguous bytes of memory get moved. It does not matter how that gets done.
  • idbruceidbruce Posts: 6,197
    edited 2015-04-09 09:11
    Heater

    We all have our good points and our bad points, and we all have to accept the good with the bad. Many of the folks around here are like family, and that includes you, but like all families, we have our quabbles and quarrels. I do my best to keep in mind that we are all unique with different personalities.
    As for memcpy, the contract is that n contiguous bytes of memory get moved. It does not matter how that gets done.

    Earlier you wrote:
    3) Simply assigning structs: a = b; where a and b are the same struct type.

    It has been quite some time since I have been heavily involved in C.... Now if I am not mistaken, it isn't that easy with pointers.... Pointers have to be handled differently, don't they?
  • idbruceidbruce Posts: 6,197
    edited 2015-04-09 09:19
    Additionally:
    3) Simply assigning structs: a = b; where a and b are the same struct type.

    I have always seen memcpy for structs and such and I can't ever remember seeing a struct copied that way. Maybe I just wasn't paying close enough attention.

    Is there any benefit to a memcpy?
  • Brian FairchildBrian Fairchild Posts: 549
    edited 2015-04-09 09:24
    If propGCC complies with the C90 standard you just assign one string to the other.
    struct my_struct {
    	int x;
    	int y;
    	char a;
    };
    
    struct my_struct source_struct;
    struct my_struct dest_struct;
    
    void main(void)
    {
    
    	dest_struct = source_struct;
    
    }
    

    Under the hood it should just load three parameters (source address, dest address and length) and call a memory copy routine.
  • Heater.Heater. Posts: 21,230
    edited 2015-04-09 09:24
    idbruce,
    Pointers have to be handled differently, don't they?
    True.

    What I was suggesting is that "a" and "b" are the structures themselves not pointers to structures. Like so:
        typedef struct {
            int  a;
            char b;
        } my_struct_t;
    
        my_struct_t source = {1, 2};
        my_struct_t dest   = {3, 4};
    
        dest = source;
        // dest is now {1, 2}
    
    If "a" and "b" are pointers to structs then "a = b" only copies the pointer not the content of the struct
        my_struct_t source = {1, 2};
        my_struct_t dest   = {3, 4};
    
        my_struct_t *sourcePtr = &source;
        my_struct_t *destPtr = &dest;
    
        destPtr = sourcePtr;        // dest is unchanged.
    
Sign In or Register to comment.