how to use 'copy_to_user' with index to copy by chunks? - linux

I have a big data in the kernel (1GB+), I want to copy it to the user by chunks.
int i=0;
while (myBuffer) {
copy_to_user(userBuffer + 64*i, (void *) myBuffer, 64)
myBuffer = newData();
i++;
}
how can I do the (+ 64*i) in kernel mode.. is it legal?
I mean, when I send a buff from user to kernel, kernel want to fill it with data using 'copy_to_user' but kernel will use 'copy_to_user' several times to same userBuff, each time to different place of it.
example:
callback:
getMyData(char* userBuff){
copy_to_user(userBuff, 'H', 1);
copy_to_user(userBuff+1, 'o', 1);
copy_to_user(userBuff+2, 'w', 1);
copy_to_user(userBuff+3, ' ', 1);
copy_to_user(userBuff+4, 'a', 1);
copy_to_user(userBuff+5, 'r', 1);
copy_to_user(userBuff+6, 'e', 1);
}
user calls:
getMydata(myBuff);
print("%s",myBuff);
user expects to print:
How are
is it possible? its not the same memory...

Related

Array Set Length unequal to Sum of Array Distribution

I have a list of user ids like so: ["1111","5555","1111","8983",...]. I then compute the distribution of the frequency of the ids. But somehow adding the size of the distribution bins is smaller than the user set.
function histogram(List){
var d = {};
for(const x of List){
if (x in d){
d[x]+=1;
}
else{
d[x]=1;
}
}
return d
}
var featureuserids = f1_users.concat(f2_users,f3_users,f4_users)
var featureusers = [...new Set(featureuserids)];
const featurehist = histogram(Object.values(histogram(featureuserids)))
const n_featureusers = featureusers.length
Here is an example output.
Feature Users: 17379
Feature Hist: { '1': 16359, '2': 541, '3': 93, '4': 6 }
What is my mistake?
I have found the answer. One of my Lists (f1_users) had saved the ids as int, while the others were in string format. Therefore they were counted double in the set. After converting them all to string the issue was fixed.

How to avoid memory leaks when building a slice of slices using ArrayLists

I'm trying to build a slice of slices using multiple std.ArrayLists.
The code below works, but the memory allocator std.testing.allocator warns me of a memory leaks wherever I append new elements to a sublist.
const std = #import("std");
const mem = std.mem;
fn sliceOfSlices(allocator: *mem.Allocator) ![][]usize {
var list = std.ArrayList([]usize).init(allocator);
var i: usize = 0;
while (i < 3) : (i += 1) {
var sublist = std.ArrayList(usize).init(allocator);
// errdefer sublist.deinit(); // here?
var n: usize = 0;
while (n < 5) : (n += 1) {
try sublist.append(n); // leaks
// errdefer sublist.deinit(); // here?
// errdefer allocator.free(sublist.items);
}
try list.append(sublist.toOwnedSlice());
}
return list.toOwnedSlice();
}
const testing = std.testing;
test "memory leaks" {
const slice = try sliceOfSlices(testing.allocator);
testing.expectEqual(#intCast(usize, 3), slice.len);
testing.expectEqual(#intCast(usize, 5), slice[0].len);
}
I tried to use errdefer in several places to free the allocated sublist, but it didn't work. From the documentation it seems a lifetime issue, but I'm not sure how to handle it.
the std.ArrayList(T).items slice has a lifetime that remains valid until the next time the list is resized, such as by appending new elements.
— https://ziglang.org/documentation/master/#Lifetime-and-Ownership
What's the appropriate error handling when list.append() fails?
I am a beginner to zig so perhaps I am totally wrong here, but I think the reason why you are getting the memory leak is not because something failed!
As you use ArrayList its memory is allocated via an allocator, the memory has explicitly to be freed at end of usage. For an ArrayList you could simply use the deinit() function. However as your function sliceOfSlices() converts that ArrayList wrapper to a slice, you have to use testing.allocator.free(slice) to get rid of the memory used by that slice.
But note: every element of your slice is itself a slice (or a pointer to it). Also obtained via ArrayList.toOwnedSlice(). Therefore those slices you have also to get rid of, before you can deallocate the containing slice.
So I would change your test to
test "memory leaks" {
const slice = try sliceOfSlices(testing.allocator);
defer {
for (slice) |v| {
testing.allocator.free(v);
}
testing.allocator.free(slice);
}
testing.expectEqual(#intCast(usize, 3), slice.len);
testing.expectEqual(#intCast(usize, 5), slice[0].len);
}
and now no memory leak should occur anymore.
Perhaps somebody knows a better solution, but lacking experience here, this would be the way to go, IMO.
And after some thinking, answering your question what to do in case of an error, I would rewrite your function sliceOfSlices() to
fn sliceOfSlices(allocator: *mem.Allocator) ![][]usize {
var list = std.ArrayList([]usize).init(allocator);
errdefer {
for (list.items) |slice| {
allocator.free(slice);
}
list.deinit();
}
var i: usize = 0;
while (i < 3) : (i += 1) {
var sublist = std.ArrayList(usize).init(allocator);
errdefer sublist.deinit();
var n: usize = 0;
while (n < 5) : (n += 1) {
try sublist.append(n);
}
try list.append(sublist.toOwnedSlice());
}
return list.toOwnedSlice();
}
Now if any error happened in your function, both list and sublist should be cleaned up properly. Still if no error was returned from the function, your calling code would be responsible for the cleanup to avoid memory leaks like implemented in the test block above.

Clear multiple lines from stdout

I am trying to write multiple lines to the console in Node.JS then clear all of the lines I wrote.
process.stdout.write(['a', 'b', 'c'].join('\n'))
setInterval(() => {
process.stdout.clearLine(0);
process.stdout.write(['d', 'e', 'f'].join('\n'));
}, 1000)
I've seen some solutions that clear the whole console, I do not want this. I just want to clear what I've written to the screen.
I don't know of there is better way to do this, but what I do is move the cursor up 1 line at the time and than clear that line.
const clearLines = (n) => {
for (let i = 0; i < n; i++) {
//first clear the current line, then clear the previous line
const y = i === 0 ? null : -1
process.stdout.moveCursor(0, y)
process.stdout.clearLine(1)
}
process.stdout.cursorTo(0)
}

how to make Jest continue to run after fail case in expect

When I run this code, the test stops on its first failure case and I was wondering how I can get it to continue going after failure until it completely iterates over the array:
it('b contains all elements in a', () => {
const a = ['a', 'b', 'c', 'd'];
const b = ['e', 'f', 'g', 'i'];
for (let i = 0; i < a.length; i += 1) {
expect(b).toContain(a[i]);
}
});

emit to specifics sockets (like a whisper) which contain specific socket.name

I have my sockets stored like this in an object "people" . but now I would like to extract coincidences in people.name with an object like ["4323","9","43535"] for example 9. meaning extract in this case "OGyF_FMFbsr0ldcbAAAK" socket.
In a few words navigate through ["4323","9","43535"] and find if they are in people , so then emit a notification to the socket which contain people.name === 9 . Could be more than one socket.
So.
for each "attending"
["4323","9","43535"]
in "people"
{
"ZA-CJOc1PtiwDVxkAAAD":
{"name":"4","owns":"2-0-62","inroom":"2-0-62","device":"desktop"},
"wKg2rcFSHgcl4m3WAAAG":
{"name":"3","owns":"2-0-110","inroom":"2-0-110","device":"desktop"},
"OGyF_FMFbsr0ldcbAAAK":
{"name":"9","owns":null,"inroom":null,"device":"desktop"}
}
then emit
io.sockets.socket(id).emit("notification", result);
QUESTIONS:
How do I make the right code to select sockets to send notification?
How then would emit the notification for each one?
thanks in advance
If I understand what you're asking correctly, then one way to do this is to iterate over the keys of your people object, compare the name properties of each of them with the elements in your attending array, and push any matching keys into a new array found to get a list of people whose name is found in your attending list.
You can then iterate over the found array to emit messages to clients in your people object that match your search criteria.
var attending = ['4323', '9', '43535'],
found = [];
var people = {
'ZA-CJOc1PtiwDVxkAAAD': {
'name': '4', 'owns': '2-0-62', 'inroom': '2-0-62', 'device': 'desktop'
},
'wKg2rcFSHgcl4m3WAAAG': {
'name': '3', 'owns': '2-0-110', 'inroom': '2-0-110', 'device': 'desktop'
},
'OGyF_FMFbsr0ldcbAAAK': {
'name': '9', 'owns': null, 'inroom': null, 'device': 'desktop'
}
};
for (var person in people) {
for (var i = 0, numAttending = attending.length; i < numAttending; i++) {
if (people[person].name === attending[i]) {
found.push(person);
}
}
}
for (var i = 0, numFound = found.length; i < numFound; i++) {
io.sockets.socket(found[i]).emit('notification', result);
};
Edit
If you want to push whole objects onto your found array, you could do it like this. Since the entire object and not only the client id is being stored in the array, the emit loop below needs some slight adjusting to keep working.
for (var person in people) {
for (var i = 0, numAttending = attending.length; i < numAttending; i++) {
if (people[person].name === attending[i]) {
found.push(people[person]);
//this would give something like this, without the socket id
//[{"name":"3","owns":null,"inroom":null,"device":"desktop"}]
}
}
}
for (var person in found) {
io.sockets.socket(person).emit('notification', result);
};

Resources