Re: Not able to generate race condition... please help

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Please note that task_struct structure will be shared in case of kernel threads. If u use pthread library, it being a user space thread does not have a specific task_struct structure. So, kernel does not know about the user space threads. As the code has pthread library, they can share the registers. 
Any thoughts?



On Mon, May 11, 2009 at 12:13 PM, Pei Lin <telent997@xxxxxxxxx> wrote:
2009/5/8 Chetan Nanda <chetannanda@xxxxxxxxx>:
>
>
> On Fri, May 8, 2009 at 1:28 AM, seshikanth varma <seshikanthvarma@xxxxxxxxx>
> wrote:
>>
>> This is the way i have defined the variables:
>>
>> volatile int                i asm("eax"); /* For using eax ebx ecx & edx
>> for i, j , k  and l respectively.
>>
>>                                            *  All the threads shud use eax
>> for i, ebx for j ...
>>
>>                                            */
>> volatile int                j asm("ebx");
>> volatile int                k asm("ecx");
>> volatile int                l asm("edx");
>>
>> Though every thread has its own copy of registers,the registers eax, ebx
>> ecx and edx are unique by name. So, the threads should be writing to these
>> registers which means that these variables are shared.
>
>
> I am still confused, as every thread will be having its own register set and
> this set will get stored in its 'tast_struct' at each context switch and at
> next run registers will get populated from corresponding 'task_struct'.
>
> So how these variable will get shared between different threads? I am
> missing any basic thing?

because "volatile int                j asm("ebx");" u objdump the elf
will find the variables are in data section, without initial it in
.bss section. if u change code to this "register int j asm("ebx")
",run the app u will get the segmentation fault.

sandeep lahane said
"The race condition in OP's code can be easily reproduced by making the
LOOPCOUNT to 10000 and running the program multiple times on a SMP
machine."
 >>>>>>>>>>>yes, i also reproduced in my computer.

>
> Thanks,
> Chetan Nanda
>
>>
>> Regards,
>> Seshikanth
>>
>> On Fri, May 8, 2009 at 1:21 AM, Daniel Baluta <daniel.baluta@xxxxxxxxx>
>> wrote:
>>>
>>> On Thu, May 7, 2009 at 10:38 PM, seshikanth varma
>>> <seshikanthvarma@xxxxxxxxx> wrote:
>>> > Hi,
>>> > I am learning linux kernel. I have written a simple program to
>>> > understand
>>> > the usage of mutex variable.
>>> > Ideally the following program should generate race condition and should
>>> > produce the different values on i,j,k and l rather than i = j = k = l =
>>> > 100(LOOPCONSTANT * Number of threads) on usage of mutex. Here shared
>>> > variables between threads are i,j,k and l.
>>> > My kernel is not SMP.  Can u please tell me where am i going wrong?
>>> >
>>> > ======================================================================================================
>>> >
>>> > #include <pthread.h>
>>> > #include <stdio.h>
>>> > #define checkResults(string, val) {             \
>>> >     if (val) {                                     \
>>> >         printf("Failed with %d at %s", val, string); \
>>> >         exit(1);                                     \
>>> >     }                                              \
>>> > }
>>> > //#define            LOOPCONSTANT     100000
>>> > #define            LOOPCONSTANT     10
>>> > #define            THREADS          10
>>> >
>>> > pthread_mutex_t    mutex = PTHREAD_MUTEX_INITIALIZER;
>>> > volatile int                i asm("eax"); /* For using eax ebx ecx &
>>> > edx for
>>> > i, j , k  and l respectively.
>>> >
>>> >                                            *  All the threads shud use
>>> > eax
>>> > for i, ebx for j ...
>>> >
>>> >                                            */
>>> > volatile int                j asm("ebx");
>>> > volatile int                k asm("ecx");
>>> > volatile int                l asm("edx");
>>>
>>> Are you sure that this variables are shared among threads?
>>> Please keep in mind that every thread has its own copy of registers.
>>>
>>> > int                uselock=0;
>>> >
>>> > void *threadfunc(void *parm)
>>> > {
>>> >     int   loop = 0;
>>> >     int   rc;
>>> >
>>> >     for (loop=0; loop<LOOPCONSTANT; ++loop) {
>>> >         if (uselock) {
>>> >             rc = pthread_mutex_lock(&mutex);
>>> >             checkResults("pthread_mutex_lock()\n", rc);
>>> >         }
>>> >         ++i; ++j; ++k; ++l;
>>> >         if (uselock) {
>>> >             rc = pthread_mutex_unlock(&mutex);
>>> >             checkResults("pthread_mutex_unlock()\n", rc);
>>> >         }
>>> >     }
>>> >     return NULL;
>>> > }
>>> >
>>> > int main(int argc, char **argv)
>>> > {
>>> >     pthread_t             threadid[THREADS];
>>> >     int                   rc=0;
>>> >
>>> >     int                   loop=0;
>>> >     pthread_attr_t        pta;
>>> >
>>> >     printf("Entering testcase\n");
>>> >     printf("Give any number of parameters to show data corruption\n");
>>> >     if (argc != 1) {
>>> >         printf("A parameter was specified, no serialization is being
>>> > done!\n");
>>> >         uselock = 0;
>>> >     }
>>> >
>>> >     pthread_attr_init(&pta);
>>> >     pthread_attr_setdetachstate(&pta, PTHREAD_CREATE_JOINABLE);
>>> >
>>> >     printf("Creating %d threads\n", THREADS);
>>> >     for (loop=0; loop<THREADS; ++loop) {
>>> >         rc = pthread_create(&threadid[loop], &pta, threadfunc, NULL);
>>> >         checkResults("pthread_create()\n", rc);
>>> >     }
>>> >
>>> >     printf("Wait for results\n");
>>> >     for (loop=0; loop<THREADS; ++loop) {
>>> >         rc = pthread_join(threadid[loop], NULL);
>>> >         checkResults("pthread_join()\n", rc);
>>> >     }
>>> >
>>> >     printf("Cleanup and show results\n");
>>> >     pthread_attr_destroy(&pta);
>>> >     pthread_mutex_destroy(&mutex);
>>> >
>>> >     printf("\nUsing %d threads and LOOPCONSTANT = %d\n",
>>> >            THREADS, LOOPCONSTANT);
>>> >     printf("Values are: (should be %d)\n", THREADS * LOOPCONSTANT);
>>> >     printf("  ==> seshikanth | %d, %d, %d, %d\n", i, j, k, l);
>>> >
>>> >     printf("Main completed\n");
>>> >     return 0;
>>> >
>>> > }
>>> >
>>> > ======================================================================================================
>>> >
>>> > O/p of the above program:
>>> > ---------------------------------------
>>> > with userlock = 0 (i.e., shud hit race condition)
>>> > --------------------------------------------------------------------
>>> > gcc check.c -pthread
>>> > bash-2.05b$ ./a.out
>>> > Creating 10 threads
>>> > Wait for results
>>> > Cleanup and show results
>>> > Using 10 threads and LOOPCONSTANT = 10
>>> > Values are: (should be 100)
>>> >   ==> | 100, 100, 100, 100 <<<<<<<<<<<==========*******
>>> > Main completed
>>> > bash-2.05b$
>>> > =====================================
>>> > with userlock = 1;
>>> > -------------------------
>>> > I am getting the same o/p which is correct....
>>> >
>>> > Any help regarding this is greatly appreciated.
>>> > Thanks,
>>> > Seshikanth
>>> >
>>> >
>>
>
>



--
Regards,
Seshikanth

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux