Byte shifiting under msvc - visual-c++

I have a buffer where the first 4 bytes represents an unsigned 32bit integer.
The buffer looks like this {32, 0, 0, 0, ...}
The following code works under gcc without any problems:
uint32_t size = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | (buffer[3] << 24);
Size is 32 as expected but if i compile the project with msvc size is 538976288 instead of 32.
What is the problem?
EDIT:
full source code for test:
#include <stdint.h>
#include <stdio.h>
int main()
{
int pos = 0;
uint32_t buffer [] = {32, 0, 0, 0};
uint32_t size = buffer[pos++] | (buffer[pos++] << 8) | (buffer[pos++] << 16) | (buffer[pos++] << 24) ;
printf("size=%d\n", size);
return 0;
}

Related

Why did NOT my Linux act the lazy memory allocation?

I'm practising to use the Lazy Allocation and the Demand Paging policies of Linux.
I want a buffer that I allocated by mmap() occupy NO physical memory until I really write something to it.
Further more, I want it gradually enlarge (use more physical memory) with a step size of the swap page size (e.g. 4K) of Linux along with I'm writing continuously from its head to the tail.
According to some docs and searchings, it should NOT enlarge if there be only reading access on it, but the reality I observed in a experiment does NOT like this.
To test this, I coded a program as following, and watched the memory status by top shell command when it running.
constexpr size_t BUF_SIZE = 1024 * 1024 * 1024;
int main( int argc, char** argv ) {
auto shm_pt = mmap( NULL, BUF_SIZE, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0 );
if( shm_pt == MAP_FAILED ) {
std::cerr << "mmap error:" << shm_pt;
exit( EXIT_FAILURE );
};
bool full_zero = true;
uint8_t* pc = reinterpret_cast<uint8_t*>( shm_pt );
constexpr size_t STEP_SIZE = 1024 * 1024;
for( size_t j = 0; j < BUF_SIZE / STEP_SIZE; ++j ) {
this_thread::sleep_for( 100ms );
size_t base = j * STEP_SIZE;
std::cerr << "Reading from " << base / 1024 / 1024 << "M..." << endl;
for( size_t i = 0; i < STEP_SIZE; ++i )
full_zero = full_zero && pc[ base + i ] == 0;
}
if( !full_zero )
std::cerr << "The buffer has not been initialized with full zeros!";
for( size_t j = 0; j < BUF_SIZE / STEP_SIZE; ++j ) {
this_thread::sleep_for( 100ms );
size_t base = j * STEP_SIZE;
std::cerr << "Writing to " << base / 1024 / 1024 << "M..." << endl;
for( size_t i = 0; i < STEP_SIZE; ++i )
pc[ base + i ] = 'c';
}
munmap( shm_pt, BUF_SIZE );
return EXIT_SUCCESS;
};
What I observed is that the physical memory used by my app is growing gradually along with the Reading operation not with Writing op!
Perhaps my comprehension is wrong?
I got it!
In the searching content I pasted, that man used a MAP_PRIVATE flag to mmap() as argument, while I used MAP_SHARED.
It looks like that if a buffer is being shared between processes, a READING operation also results real memory allocation!

Pthreads program is slower than the serial program - Linux

Thank you for being generous with your time and helping me in this matter. I am trying to calculate the sum of the squared numbers using pthread. However, it seems that it is even slower than the serial implementation. Moreover, when I increase the number of threads the program becomes even slower. I made sure that each thread is running on a different core (I have 6 cores assigned to the virtual machine)
This is the serial program:
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <time.h>
int main(int argc, char *argv[]) {
struct timeval start, end;
gettimeofday(&start, NULL); //start time of calculation
int n = atoi(argv[1]);
long int sum = 0;
for (int i = 1; i < n; i++){
sum += (i * i);
}
gettimeofday(&end, NULL); //end time of calculation
printf("The sum of squares in [1,%d): %ld | Time Taken: %ld mirco seconds \n",n,sum,
((end.tv_sec * 1000000 + end.tv_usec) - (start.tv_sec * 1000000 + start.tv_usec)));
return 0;
}
This the Pthreads program:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
void *Sum(void *param);
// structure for thread arguments
struct thread_args {
int tid;
int a; //start
int b; //end
long int result; // partial results
};
int main(int argc, char *argv[])
{
struct timeval start, end;
gettimeofday(&start, NULL); //start time of calculation
int numthreads;
int number;
double totalSum=0;
if(argc < 3 ){
printf("Usage: ./sum_pthreads <numthreads> <number> ");
return 1;
}
numthreads = atoi(argv[1]);
number = atoi(argv[2]);;
pthread_t tid[numthreads];
struct thread_args targs[numthreads];
printf("I am Process | range: [%d,%d)\n",1,number);
printf("Running Threads...\n\n");
for(int i=0; i<numthreads;i++ ){
//Setting up the args
targs[i].tid = i;
targs[i].a = (number)*(targs[i].tid)/(numthreads);
targs[i].b = (number)*(targs[i].tid+1)/(numthreads);
if(i == numthreads-1 ){
targs[i].b = number;
}
pthread_create(&tid[i],NULL,Sum, &targs[i]);
}
for(int i=0; i< numthreads; i++){
pthread_join(tid[i],NULL);
}
printf("Threads Exited!\n");
printf("Process collecting information...\n");
for(int i=0; i<numthreads;i++ ){
totalSum += targs[i].result;
}
gettimeofday(&end, NULL); //end time of calculation
printf("Total Sum is: %.2f | Taken Time: %ld mirco seconds \n",totalSum,
((end.tv_sec * 1000000 + end.tv_usec) - (start.tv_sec * 1000000 + start.tv_usec)));
return 0;
}
void *Sum(void *param) {
int start = (*(( struct thread_args*) param)).a;
int end = (*((struct thread_args*) param)).b;
int id = (*((struct thread_args*)param)).tid;
long int sum =0;
printf("I am thread %d | range: [%d,%d)\n",id,start,end);
for (int i = start; i < end; i++){
sum += (i * i);
}
(*((struct thread_args*)param)).result = sum;
printf("I am thread %d | Sum: %ld\n\n", id ,(*((struct thread_args*)param)).result );
pthread_exit(0);
}
Results:
hamza#hamza:~/Desktop/lab4$ ./sum_serial 10
The sum of squares in [1,10): 285 | Time Taken: 7 mirco seconds
hamza#hamza:~/Desktop/lab4$ ./sol 2 10
I am Process | range: [1,10)
Running Threads...
I am thread 0 | range: [0,5)
I am thread 0 | Sum: 30
I am thread 1 | range: [5,10)
I am thread 1 | Sum: 255
Threads Exited!
Process collecting information...
Total Sum is: 285.00 | Taken Time: 670 mirco seconds
hamza#hamza:~/Desktop/lab4$ ./sol 3 10
I am Process | range: [1,10)
Running Threads...
I am thread 0 | range: [0,3)
I am thread 0 | Sum: 5
I am thread 1 | range: [3,6)
I am thread 1 | Sum: 50
I am thread 2 | range: [6,10)
I am thread 2 | Sum: 230
Threads Exited!
Process collecting information...
Total Sum is: 285.00 | Taken Time: 775 mirco seconds
hamza#hamza:~/Desktop/lab4$
The two programs do very different things. For example, the threaded program produces much more text output and creates a bunch of threads. You're comparing very short runs (less than a thousandth of a second) so the overhead of those additional things is significant.
You have to test with much longer runs such that the cost of producing additional output and creating and synchronizing threads is lost.
To use an analogy, one person can tighten three screws faster than three people can because of the overhead of getting a tool to each person, deciding who will tighten which screw, and so on. But if you have 500 screws to tighten, then three people will get it done faster.

Control FlashAir SD card from Linux User Space

I want to control FlashAir SD card from Linux User Space. I decide to choose mmc ioctl to send command to SD card. I have refer to here and here
My code is
#define MMC_BLOCK_MAJOR 179
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <linux/mmc/ioctl.h>
#include <linux/ioctl.h>
#include <linux/types.h>
#include <sys/ioctl.h>
#define MMC_RSP_PRESENT (1 << 0)
#define MMC_RSP_136 (1 << 1) /* 136 bit response */
#define MMC_RSP_CRC (1 << 2) /* expect valid crc */
#define MMC_RSP_BUSY (1 << 3) /* card may send busy */
#define MMC_RSP_OPCODE (1 << 4) /* response contains opcode */
#define MMC_RSP_SPI_S1 (1 << 7) /* one status byte */
#define MMC_RSP_R1 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)
#define MMC_RSP_R3 (MMC_RSP_PRESENT)
#define MMC_SEND_STATUS 13
#define MMC_READ_SINGLE_BLOCK 17
#define READ_MULTIPLE_BLOCK 18
#define MMC_READ_EXTR_SINGLE 48
#define MMC_DATA_READ (1 << 9)
#define MMC_CMD_AC (0 << 5)
#define MMC_CMD_ADTC (1 << 5)
#define MMC_CMD_BC (2 << 5)
#define MMC_CMD_BCR (3 << 5)
uint8_t data_buffer[512];
int main(int argc, char *argv[])
{
int i, fd;
int ret = 0;
struct mmc_ioc_cmd cmd;
uint8_t mio = 1, func = 1;
uint16_t count = 0x200;
uint32_t addr = 0x400;
uint32_t offset = addr & 0x1FF;
if (offset + count > 512) count = 512 - offset;
uint32_t arg =
(((uint32_t)mio & 0x1) << 31) |
(mio ? (((uint32_t)func & 0x7) << 28) : (((uint32_t)func & 0xF) << 27)) |
((addr & 0x1FFFF) << 9) |
((count - 1) & 0x1FF);
fd = open("/dev/mmcblk0", O_WRONLY);
if(fd < 0)
{
perror("file open");
return fd;
}
#if 1 // CMD48
memset(&cmd, 0, sizeof(struct mmc_ioc_cmd));
memset(data_buffer, 0, sizeof(data_buffer));
cmd.opcode = MMC_READ_EXTR_SINGLE;
cmd.arg = 0x900001ff;
cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
cmd.blksz = 512;
cmd.blocks = 1;
mmc_ioc_cmd_set_data(cmd, &data_buffer); // I also try with mmc_ioc_cmd_set_data(cmd, data_buffer)
ret = ioctl(fd, MMC_IOC_CMD, &cmd);
printf("MMC_READ_EXTR_SINGLE response[0] = %x\n", cmd.response[0]);
printf("ret = %d\n", ret);
printf("data_buffer[1] = %d\n", data_buffer[1]);
printf("data_buffer[2] = %d\n", data_buffer[2]);
#endif
#if 1 // CMD17
memset(&cmd, 0, sizeof(struct mmc_ioc_cmd));
memset(data_buffer, 0, sizeof(data_buffer));
cmd.opcode = MMC_READ_SINGLE_BLOCK;
cmd.arg = 0x0;
cmd.flags = 0xb5;
cmd.blksz = 512;
cmd.blocks = 1;
mmc_ioc_cmd_set_data(cmd, &data_buffer); // I also try with mmc_ioc_cmd_set_data(cmd, data_buffer)
ret = ioctl(fd, MMC_IOC_CMD, &cmd);
printf("READ_MULTIPLE_BLOCK response[0] = %x\n", cmd.response[0]);
printf("ret = %d\n", ret);
printf("data_buffer[1] = %d\n", data_buffer[1]);
printf("data_buffer[2] = %d\n", data_buffer[2]);
#endif
close(fd);
return 1;
}
The ret = 0 ( It seems that there is no error) but the data_buffer[i] always get the value 0.
Actually, I want to create an example like Arduino example at this but I use a custom board with Linux.
Thanks for any help!

Pthread create function

I am having difficulty understanding the creation of a pthread.
This is the function I declared in the beginning of my code
void *mini(void *numbers); //Thread calls this function
Initialization of thread
pthread_t minThread;
pthread_create(&minThread, NULL, (void *) mini, NULL);
void *mini(void *numbers)
{
min = (numbers[0]);
for (i = 0; i < 8; i++)
{
if ( numbers[i] < min )
{
min = numbers[i];
}
}
pthread_exit(0);
}
numbers is an array of integers
int numbers[8];
Im not sure if I created the pthread correctly.
In the function, mini, I get the following error about setting min (declared as an int) equal to numbers[0]:
Assigning to 'int' from incompatible type 'void'
My objective is to compute the minimum value in numbers[ ] (min) in this thread and use that value later to pass it to another thread to display it. Thanks for any help I can get.
You need to pass 'numbers' as the last argument to pthread_create(). The new thread can then call 'mini' on its own stack with 'numbers' as the argument.
In 'mini', you shoudl cast the void* back to an integer array in order to dereference it correctly - you cannot dereference a void* directly - it does not point to anything:)
Also, it's very confusing to have multiple vars in different threads with the name 'numbers'.
There are some minor improprieties in this pgm but it illustrates basically what you want to do. You should play around, break and improve it.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *mini(void *numbs)
{
int *numbers = (int *) numbs;
int *min = malloc(sizeof(int));
*min = (numbers[0]);
for (int i = 0; i < 8; i++)
if (numbers[i] < *min )
*min = numbers[i];
pthread_exit(min);
}
int main(int argc, char *argv[])
{
pthread_t minThread;
int *min;
int numbers[8] = {28, 47, 36, 45, 14, 23, 32, 16};
pthread_create(&minThread, NULL, (void *) mini, (void *) numbers);
pthread_join(minThread, (void *) &min);
printf("min: %d\n", *min);
free(min);
return(0);
}

why iconv read more bytes than i specified

I use
size_t iconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
to convert UTF-16BE to GB2312.
inbytesleft is bytes number to be convert. After conversion, inbytesleft is bytes number of not converted.
After one call, I found inbytesleft is -2, according to iconv man page this function should read at most inbytesleft.
Who can tell my why and how to fix this?
code to be convert is
"保单验证"
Thanks
How are you getting the input data into your program?
I've tested the situation using this code and it seems to work:
#include <stdio.h>
#include <iconv.h>
#include <errno.h>
int main(){
char data[10] = {0x4f,0xdd,0x53,0x55,0x9a,0x8c,0x8b,0xc1, 0, 0};
char outdata[20];
char *dataptr;
char *outdataptr;
iconv_t cd;
size_t result;
size_t inbytesleft = 8;
size_t outbytesleft = 20;
int i;
cd = iconv_open("GB2312", "UTF-16BE");
dataptr = data;
outdataptr = outdata;
result = iconv(cd, &dataptr, &inbytesleft, &outdataptr, &outbytesleft);
if(result == -1)
printf("Error: %d\n", errno);
printf(" result: %zd\n", result);
printf(" inbytesleft: %zd\n", inbytesleft);
printf("outbytesleft: %zd\n", outbytesleft);
for(i = 20; i > outbytesleft; i--){
if(i != 20)
printf(",");
printf("0x%02x", *((unsigned char *)&(outdata[20-i])));
}
printf("\n");
return 0;
}
It prints
result: 0
inbytesleft: 0
outbytesleft: 12
0xb1,0xa3,0xb5,0xa5,0xd1,0xe9,0xd6,0xa4
Which appears to be correct.
The array of items in the variable data is the UTF-16BE encoding of 保单验证
If this doesn't help, could you post your code for analysis?

Resources