From mboxrd@z Thu Jan 1 00:00:00 1970 From: hs@denx.de (Heiko Schocher) Date: Fri, 04 Dec 2009 12:23:45 +0100 Subject: shared memory problem on ARM v5TE using threads Message-ID: <4B18F141.7070101@denx.de> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Hello, I have the following shared mem problem on a ARM v5TE processor using Linux version 2.6.28, -bash-3.2# cat /proc/cpuinfo Processor : Feroceon 88FR131 rev 1 (v5l) BogoMIPS : 799.53 Features : swp half thumb fastmult edsp CPU implementer : 0x56 CPU architecture: 5TE CPU variant : 0x2 CPU part : 0x131 CPU revision : 1 The testscript [1] starts 2 processes. One write process with one thread, which writes in a shared memory. The second process starts 4 threads, which all read from this shared memory. This don;t work on this processor [4]. The same demoprogramm works fine on ppc, i386 or on a ARMv6 based board [3][6] ... If I start 4 read processes, which themselves starts only one readthread [5], the demoprogramm works fine! Also, if I start one read process, which only attaches the shared memory once with shmat(), and then starts 4 read threads, and all this 4 read threads using the same shared memory addr, returned from shmat(), this works as expected. Any ideas, hints ... ? TIA bye, Heiko -- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany [1] Testscript #!/bin/sh echo "Compile" gcc -o shmtest2 shmtest2.c -lpthread echo "Run shmtest2" ./shmtest2 write 1 & ./shmtest2 read 4 & [2] demoprogramm, shmtest2.c #include #include #include #include #include #include #include extern void exit(); struct Entry { char ident_name[1000]; unsigned int tipc_nr; unsigned int pid; unsigned int in_msg; unsigned int out_msg; unsigned int rxQueueLength; }; void* attachSharedMem(int shmid) { void* addr = shmat(shmid, NULL, 0); if ((addr != 0) && (0xffffffff != (unsigned int)addr)) { printf("attach shared mem:%x\n",addr); } else { printf("shmat failed"); addr = 0; } return addr; } int createSharedMem() { key_t key = 1000; /* key to be passed to shmget() */ int shmflg; /* shmflg to be passed to shmget() */ int shmid; /* return value from shmget() */ int size; /* size to be passed to shmget() */ size = 60000; shmflg = IPC_CREAT | 0666; if ((shmid = shmget (key, size, shmflg)) == -1) { printf("shmget failed"); shmid = 0; } printf("Shared memory Id:%d\n",shmid); return shmid; } void* setupSharedMem() { int shmid = createSharedMem(); void* addrShm = attachSharedMem(shmid); return addrShm; } void *readThread(void *t) { struct Entry* entry = 0; int shmid = (int)t; void* addrShm = attachSharedMem(shmid); if (addrShm != 0) { printf("Start Read Thread addr:%x\n",addrShm); entry = (struct Entry*)addrShm; entry->in_msg = 0; entry->out_msg = 0; int i=0; while(i < 60) { entry->in_msg += 1000; sleep(1); printf("Read from entry in_msg=%d, out_msg=%d, addr=%x\n",entry->in_msg,entry->out_msg, addrShm); i++; } } pthread_exit(NULL); } void *writeThread(void *t) { struct Entry* entry = 0; unsigned int threadId = (unsigned int)t; void* addrShm = setupSharedMem(); if (addrShm != 0) { printf("Start Write Thread %d, addr:%x\n",threadId,addrShm); entry = (struct Entry*)addrShm; strcpy(entry->ident_name,"this is a test entry"); entry->in_msg = 0; entry->out_msg = 0; entry->rxQueueLength = 20000; entry->pid = threadId; entry->tipc_nr = 1000; int i=0; while(i < 60) { entry->out_msg += 1000; sleep(1); i++; } } pthread_exit(NULL); } main(int argc, char* argv[]) { //check the arguments if (argc != 3) { printf("Arguments are [read|write] [number of threads]\n"); exit(1); } unsigned int mode = 0; unsigned int nbrOfThreads = 0; if (strcmp(argv[1],"write") == 0) { printf("Write to in_msg\n"); mode = 1; } if (strcmp(argv[1],"read") == 0) { printf("Read from in_msg\n"); mode = 2; } nbrOfThreads = atoi(argv[2]); pthread_t threads[nbrOfThreads]; pthread_attr_t attr; /* Initialize and set thread detached attribute */ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); unsigned int t; int rc; for(t=0; t