Can a struct in UPC have shared array as a field? - parallel-processing

I need to store shared array inside a struct in UPC. Is it possible to do?

Struct fields cannot be shared-qualified, for the same reason they cannot be declared with static or extern - a struct field does not carry independent storage-class information (ie because the fields of a struct are always stored contiguously, and could be used for example to declare a stack variable).
However, a struct may contain an array field, and the struct can then be used to define a shared object, eg:
struct S {
int array[100];
int foo;
};
shared struct S data[THREADS];
...
data[MYTHREAD].array[0] = MYTHREAD;
However note the distribution of data in this example is one struct per thread, the array field is not independently distributed across threads.
A struct may also contain a pointer to a shared array, eg:
#include <upc.h>
struct R {
shared int *sa;
int bar;
};
...
struct R r;
r.sa = upc_all_alloc(THREADS, sizeof(int));
r.sa[MYTHREAD] = MYTHREAD;
in this case the shared array is distributed across threads, but the storage is not embedded in the struct - the struct field is just a pointer-to-shared (and thanks to C rules can be accessed with array syntax).

Related

Struct mutation & memory management

I know structs are made for the purpose of being immutable but I don’t quietly understand the concept of “when we change a property in struct, the whole struct gets destroyed and created again” so now when we have a simple struct like:
`
enter code here`struct MyStruct { var num: Int }
var sample = MyStruct(num: 1)
var sample2 = sample
sample.num.address (unsafePointer) // address: 0x0000678ed8
Now if we change sample’s num property,
sanple.num = 2
Will its address in memory change? Or the struct just gets recreated at the ‘same’ address in memory? I’m really confused cause the address of properties do not change!!!

How to check if a cJSON pointer was initialized/set earlier?

I have a struct with cJSON pointers as in:
struct {
cJSON *myJSON1;
cJSON *myJSON2;
...
} myStruct;
Somewhere in my code I create cJSON items as in myStruct.myJSON1 = cJSON_CreateObject()
At the end of the code, I want to call cJSON_Delete() on those pointers which were assigned. I presume this is the classic C case where there is no way to find out if the pointer was malloced in some way. Of course, I can keep a flag to keep track but I want a simple way. I read...
The cJSON struct is as:
/* The cJSON structure: */
typedef struct cJSON
{
struct cJSON *next;
struct cJSON *prev;
struct cJSON *child;
int type;
char *valuestring;
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
int valueint;
double valuedouble;
char *string;
} cJSON;
The function cJSON_Invalid() is available. The documentation states "(check with cJSON_IsInvalid): Represents an invalid item that doesn't contain any value. You automatically have this type if you set the item to all zero bytes." Do I have to memset the structure to 0 or just type?
In other words, my question is: What would be the easiest way to check if a cJSON pointer is malloced without creating an additional variable? Perhaps set "type" to zero? I can try such options but I want a definite answer which works in all situations.
If you just have an uninitialized pointer to a cJSON data structure the behavior is undefined.
I.e. for cJSON *myJSON1;
cJSON_Invalid(myJSON1) might return 0 or 1.
And cJSON_Delete(myJSON1) will probably segfault. Or do nothing if you get lucky.
The solution is to always initialize cJSON data structures to NULL.
Then you can just call cJSON_Delete(). If the pointer is still NULL the call will do nothing. If it was set up at some point in your program it will correctly release all the memory.
Since you have a structure of multiple cJSON pointers you can set the entire data structure to 0 using memset.
You can take a look at the source code.
CJSON_PUBLIC(void) cJSON_Delete(cJSON *item)
{
cJSON *next = NULL;
while (item != NULL)
{
...
}
}

Declaring structure with itself?

I've begun studying data structures, and the linked list popped up. The idea behind a linked list is simple, but the implementation (I use c++) is a bit confusing, especially regarding the nodes used in linked lists. The way a node is defined for a singly linked list in C++ is as follows
// A linked list node
struct Node {
int data;
struct Node* next;
};
or if we were using classes, then it is defined like this.
class Node {
public:
int data;
Node* next;
};
My confusion arises here. How can one define another struct inside struct Node with the same name? I see that the new struct is a pointer to a node, but how does this implementation actually work? It's really confusing :(
How can one define another struct inside struct Node with the same name?
That's not what's happening. You can omit the struct keyword in the data member declaration struct Node* next; such that it might be easier to digest:
struct Node {
int data;
Node* next;
};
Except access specifier (the public), this is now identical to the class version, and it can become clear that you don't define a new struct Node inside of Node, but instead you declare a data member next that is a pointer to an instance of type Node. A pointer on a 64bit machine will need 64bit, that's why the compiler can work with this definition of Node, as the size it must reserve for Node instances is known.
To declare a pointer to something you do not need definition of the class, only its declaration. Therefore this is not recursive definition and the compiler won't run into problems.
You can think of it this way: The pointer member will be the same size whatever the type of the pointer, it still needs only the capacity to address a place anywhere in memory.

Using (sub)struct located in other package in Datastore

I haven't been able to find any information related to this.. let's say you call an API and save the resulted json into a struct in package Foo, like this:
package foo
type FooData struct {
A string `json:"c"`
B int `json:"c"`
C int64 `json:"c"`
}
Then you have your own model package:
package bar
import (
"github.com/bla/bla/foo"
)
type BarData struct {
A float
Foo foo.FooData
}
Is this possible? Is there anything negative about doing it this way? The reason is the structs are over a hundred lines, so I feel it would be wasteful to duplicate it.
Also, what if I only want to index in B? Then I can just change it to:
type FooData struct {
A string `datastore:",noindex" `json:"c"`
B int `json:"c"`
C int64 `datastore:",noindex" `json:"c"`
}
?
Edit: Just to make it clear, my intention is to save the BarData struct in Datastore
The Go Datastore package has some documentation relating to this - https://cloud.google.com/appengine/docs/standard/go/datastore/reference#hdr-Structured_Properties
"Structured Properties
If the struct pointed to contains other structs, then the nested or embedded structs are flattened. For example, given these definitions:
type Inner1 struct {
W int32
X string
}
type Inner2 struct {
Y float64
}
type Inner3 struct {
Z bool
}
type Outer struct {
A int16
I []Inner1
J Inner2
Inner3
}
then an Outer's properties would be equivalent to those of:
type OuterEquivalent struct {
A int16
IDotW []int32 `datastore:"I.W"`
IDotX []string `datastore:"I.X"`
JDotY float64 `datastore:"J.Y"`
Z bool
}
If Outer's embedded Inner3 field was tagged as datastore:"Foo" then the equivalent field would instead be: FooDotZ bool datastore:"Foo.Z".
If an outer struct is tagged "noindex" then all of its implicit flattened fields are effectively "noindex"."
So there shouldn't be any issues with you storing nested structs, just be aware that they will be flattened in datastore. It also mentions the no indexing, saying any field inherits a "noindex" from its parent struct. I don't see why your "noindex" tagging of the inner fields wouldn't work.

structure implementation for linked list

When I was reading about Linked list, I came to know that the structure for linked list as
Struct node{
Struct node *next;
int value;
}
Why is the Struct node *next? Why cant it just be an integer pointer? Like below
Struct node{
int *next;
int value;
}
why can't this hold the next node's address? Can anyone please give me explanation?
That's actually what a pointer (*next) does. It holds the address of something else. The type definition describes what this something else is (in this case struct node). Otherwise the application would not know how many bytes to read and how to interpret the data.
Read more about pointers.
Btw. int *next would hold the address of an integer.
Why is the Struct node *next? Why cant
it just be an integer pointer?
Because then you would be pointing to the address of the next integer. This could be used to retrieve the value of the next int, but nothing more, so from there on onward, you would be stuck.
By linking nodes together, which hold integer values, you can traverse the nodes and retrieve the int values.

Resources